From bf8c1c2cfb653edeede2de053522f4cc3bbb1511 Mon Sep 17 00:00:00 2001 From: Matteo Cusini Date: Fri, 26 Jul 2024 16:29:49 -0700 Subject: [PATCH 001/102] Add ImmiscibleMultiphaseFlow physics package. --- .../immiscible_2phaseFlow_1d.xml | 145 +++ .../fluidFlow/ImmiscibleMultiphaseFlow.cpp | 1152 +++++++++++++++++ .../fluidFlow/ImmiscibleMultiphaseFlow.hpp | 389 ++++++ 3 files changed, 1686 insertions(+) create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscible_2phaseFlow_1d.xml create mode 100644 src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp create mode 100644 src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscible_2phaseFlow_1d.xml b/inputFiles/immiscibleMultiphaseFlow/immiscible_2phaseFlow_1d.xml new file mode 100644 index 00000000000..0c928a15e2b --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscible_2phaseFlow_1d.xml @@ -0,0 +1,145 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp new file mode 100644 index 00000000000..db3a431bcd0 --- /dev/null +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp @@ -0,0 +1,1152 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * SPDX-License-Identifier: LGPL-2.1-only + * + * Copyright (c) 2016-2024 Lawrence Livermore National Security LLC + * Copyright (c) 2018-2024 Total, S.A + * Copyright (c) 2018-2024 The Board of Trustees of the Leland Stanford Junior University + * Copyright (c) 2018-2024 Chevron + * Copyright (c) 2019- GEOS/GEOSX Contributors + * All rights reserved + * + * See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details. + * ------------------------------------------------------------------------------------------------------------ + */ + +/** + * @file ImmiscibleMultiphaseFlow.cpp + */ + +#include "ImmiscibleMultiphaseFlow.hpp" + +#include "constitutive/ConstitutiveManager.hpp" +#include "constitutive/capillaryPressure/CapillaryPressureFields.hpp" +#include "constitutive/capillaryPressure/capillaryPressureSelector.hpp" +#include "constitutive/ConstitutivePassThru.hpp" + +#if defined( __INTEL_COMPILER ) +#pragma GCC optimize "O0" +#endif + +namespace geos +{ + +using namespace dataRepository; +using namespace constitutive; + +ImmiscibleMultiphaseFlow::ImmiscibleMultiphaseFlow( const string & name, + Group * const parent ) + : + FlowSolverBase( name, parent ), + m_numPhases( 2 ), + m_hasCapPressure( 0 ) +{ + this->registerWrapper( viewKeyStruct::inputTemperatureString(), &m_inputTemperature ). + setInputFlag( InputFlags::REQUIRED ). + setDescription( "Temperature" ); +} + +void ImmiscibleMultiphaseFlow::postInputInitialization() +{ + FlowSolverBase::postInputInitialization(); +} + +void ImmiscibleMultiphaseFlow::registerDataOnMesh( Group & meshBodies ) +{ + using namespace fields::flow; + + FlowSolverBase::registerDataOnMesh( meshBodies ); + + DomainPartition const & domain = this->getGroupByPath< DomainPartition >( "/Problem/domain" ); + ConstitutiveManager const & cm = domain.getConstitutiveManager(); + + // 0. Find a "reference" fluid model name (at this point, models are already attached to subregions) + forDiscretizationOnMeshTargets( meshBodies, [&]( string const &, + MeshLevel & mesh, + arrayView1d< string const > const & regionNames ) + { + mesh.getElemManager().forElementSubRegions( regionNames, + [&]( localIndex const, + ElementSubRegionBase & subRegion ) + { + // If at least one region has a capillary pressure model, consider it enabled for all + string const capPresName = getConstitutiveName< CapillaryPressureBase >( subRegion ); + if( !capPresName.empty() ) + { + m_hasCapPressure = true; + } + } ); + } ); + + m_numDofPerCell = m_numPhases; + + // 2. Register and resize all fields as necessary + forDiscretizationOnMeshTargets( meshBodies, [&]( string const &, + MeshLevel & mesh, + arrayView1d< string const > const & regionNames ) + { + mesh.getElemManager().forElementSubRegions( regionNames, + [&]( localIndex const, + ElementSubRegionBase & subRegion ) + { + if( m_hasCapPressure ) + { + subRegion.registerWrapper< string >( viewKeyStruct::capPressureNamesString() ). + setPlotLevel( PlotLevel::NOPLOT ). + setRestartFlags( RestartFlags::NO_WRITE ). + setSizedFromParent( 0 ). + setDescription( "Name of the capillary pressure constitutive model to use" ). + reference(); + + string & capPresName = subRegion.getReference< string >( viewKeyStruct::capPressureNamesString() ); + capPresName = getConstitutiveName< CapillaryPressureBase >( subRegion ); + GEOS_THROW_IF( capPresName.empty(), + GEOS_FMT( "{}: Capillary pressure model not found on subregion {}", + getDataContext(), subRegion.getDataContext() ), + InputError ); + } + + + string const & fluidName = subRegion.getReference< string >( viewKeyStruct::fluidNamesString() ); + MultiFluidBase const & fluid = getConstitutiveModel< MultiFluidBase >( subRegion, fluidName ); + + // The resizing of the arrays needs to happen here, before the call to initializePreSubGroups, + // to make sure that the dimensions are properly set before the timeHistoryOutput starts its initialization. + subRegion.registerField< phaseVolumeFraction >( getName() ). + setDimLabels( 1, fluid.phaseNames() ). + reference().resizeDimension< 1 >( m_numPhases ); + + subRegion.registerField< phaseMobility >( getName() ). + setDimLabels( 1, fluid.phaseNames() ). + reference().resizeDimension< 1 >( m_numPhases ); + + subRegion.registerField< dPhaseMobility >( getName() ). + reference().resizeDimension< 1, 2 >( m_numPhases, m_numPhases ); // dP, dT, dC + + subRegion.registerField< phaseVolumeFraction_n >( getName() ). + reference().resizeDimension< 1 >( m_numPhases ); + } ); + + FaceManager & faceManager = mesh.getFaceManager(); + { + faceManager.registerField< totalMassFlux >( getName() ); + // TODO: add conditional registration later, this is only needed when there is a face-based Dirichlet BC + faceManager.registerField< facePressure >( getName() ); + faceManager.registerField< faceTemperature >( getName() ); + } + } ); +} + +void ImmiscibleMultiphaseFlow::setConstitutiveNames( ElementSubRegionBase & subRegion ) const +{ + string & fluidName = subRegion.getReference< string >( viewKeyStruct::fluidNamesString() ); + fluidName = getConstitutiveName< MultiFluidBase >( subRegion ); + GEOS_THROW_IF( fluidName.empty(), + GEOS_FMT( "{}: Fluid model not found on subregion {}", + getDataContext(), subRegion.getDataContext() ), + InputError ); + + string & relPermName = subRegion.registerWrapper< string >( viewKeyStruct::relPermNamesString() ). + setPlotLevel( PlotLevel::NOPLOT ). + setRestartFlags( RestartFlags::NO_WRITE ). + setSizedFromParent( 0 ). + setDescription( "Name of the relative permeability constitutive model to use" ). + reference(); + + relPermName = getConstitutiveName< RelativePermeabilityBase >( subRegion ); + + GEOS_THROW_IF( relPermName.empty(), + GEOS_FMT( "{}: Relative permeability model not found on subregion {}", + getDataContext(), subRegion.getDataContext() ), + InputError ); +} + +void ImmiscibleMultiphaseFlow::initializePreSubGroups() +{ + FlowSolverBase::initializePreSubGroups(); + + DomainPartition & domain = this->getGroupByPath< DomainPartition >( "/Problem/domain" ); + ConstitutiveManager const & cm = domain.getConstitutiveManager(); + + // 1. Validate various models against each other (must have same phases and components) + validateConstitutiveModels( domain ); + + // 2. Set the value of temperature + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, + MeshLevel & mesh, + arrayView1d< string const > const & regionNames ) + + { + mesh.getElemManager().forElementSubRegions( regionNames, + [&]( localIndex const, + ElementSubRegionBase & subRegion ) + { + arrayView1d< real64 > const temp = subRegion.getField< fields::flow::temperature >(); + temp.setValues< parallelHostPolicy >( m_inputTemperature ); + } ); + } ); +} + +void ImmiscibleMultiphaseFlow::validateConstitutiveModels( DomainPartition const & domain ) const +{ + GEOS_MARK_FUNCTION; + + ConstitutiveManager const & cm = domain.getConstitutiveManager(); + MultiFluidBase const & referenceFluid = cm.getConstitutiveRelation< MultiFluidBase >( m_referenceFluidModelName ); + + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, + MeshLevel const & mesh, + arrayView1d< string const > const & regionNames ) + + { + mesh.getElemManager().forElementSubRegions( regionNames, + [&]( localIndex const, + ElementSubRegionBase const & subRegion ) + { + + string const & fluidName = subRegion.getReference< string >( viewKeyStruct::fluidNamesString() ); + MultiFluidBase const & fluid = getConstitutiveModel< MultiFluidBase >( subRegion, fluidName ); + compareMultiphaseModels( fluid, referenceFluid ); + compareMulticomponentModels( fluid, referenceFluid ); + + string const & relpermName = subRegion.getReference< string >( viewKeyStruct::relPermNamesString() ); + RelativePermeabilityBase const & relPerm = getConstitutiveModel< RelativePermeabilityBase >( subRegion, relpermName ); + compareMultiphaseModels( relPerm, referenceFluid ); + + } ); + } ); +} + +void ImmiscibleMultiphaseFlow::updateFluidModel( ObjectManagerBase & dataGroup ) const +{ + GEOS_MARK_FUNCTION; + + arrayView1d< real64 const > const pres = dataGroup.getField< fields::flow::pressure >(); + arrayView1d< real64 const > const temp = dataGroup.getField< fields::flow::temperature >(); + + string const & fluidName = dataGroup.getReference< string >( viewKeyStruct::fluidNamesString() ); + MultiFluidBase & fluid = getConstitutiveModel< MultiFluidBase >( dataGroup, fluidName ); +} + +void ImmiscibleMultiphaseFlow::updateRelPermModel( ObjectManagerBase & dataGroup ) const +{ + GEOS_MARK_FUNCTION; + + arrayView2d< real64 const, compflow::USD_PHASE > const phaseVolFrac = + dataGroup.getField< fields::flow::phaseVolumeFraction >(); + + string const & relPermName = dataGroup.getReference< string >( viewKeyStruct::relPermNamesString() ); + RelativePermeabilityBase & relPerm = getConstitutiveModel< RelativePermeabilityBase >( dataGroup, relPermName ); + + constitutive::constitutiveUpdatePassThru( relPerm, [&] ( auto & castedRelPerm ) + { + typename TYPEOFREF( castedRelPerm ) ::KernelWrapper relPermWrapper = castedRelPerm.createKernelWrapper(); + + isothermalImmiscibleMultiphaseFlowKernels:: + RelativePermeabilityUpdateKernel:: + launch< parallelDevicePolicy<> >( dataGroup.size(), + relPermWrapper, + phaseVolFrac ); + } ); +} + +void ImmiscibleMultiphaseFlow::updateCapPressureModel( ObjectManagerBase & dataGroup ) const +{ + GEOS_MARK_FUNCTION; + + if( m_hasCapPressure ) + { + arrayView2d< real64 const, compflow::USD_PHASE > const phaseVolFrac = + dataGroup.getField< fields::flow::phaseVolumeFraction >(); + + string const & cappresName = dataGroup.getReference< string >( viewKeyStruct::capPressureNamesString() ); + CapillaryPressureBase & capPressure = getConstitutiveModel< CapillaryPressureBase >( dataGroup, cappresName ); + + constitutive::constitutiveUpdatePassThru( capPressure, [&] ( auto & castedCapPres ) + { + typename TYPEOFREF( castedCapPres ) ::KernelWrapper capPresWrapper = castedCapPres.createKernelWrapper(); + + isothermalImmiscibleMultiphaseFlowKernels:: + CapillaryPressureUpdateKernel:: + launch< parallelDevicePolicy<> >( dataGroup.size(), + capPresWrapper, + phaseVolFrac ); + } ); + } +} + +real64 ImmiscibleMultiphaseFlow::updateFluidState( ElementSubRegionBase & subRegion ) const +{ + GEOS_MARK_FUNCTION; + + updateFluidModel( subRegion ); + updateRelPermModel( subRegion ); + updatePhaseMobility( subRegion ); + updateCapPressureModel( subRegion ); + + return maxDeltaPhaseVolFrac; +} + +void ImmiscibleMultiphaseFlow::initializeFluidState( MeshLevel & mesh, + DomainPartition & domain, + arrayView1d< string const > const & regionNames ) +{ + GEOS_MARK_FUNCTION; + + mesh.getElemManager().forElementSubRegions( regionNames, + [&]( localIndex const, + ElementSubRegionBase & subRegion ) + { + // 2. Assume global component fractions have been prescribed. + // Initialize constitutive state to get fluid density. + updateFluidModel( subRegion ); + + // 3. Back-calculate global component densities from fractions and total fluid density + // in order to initialize the primary solution variables + string const & fluidName = subRegion.getReference< string >( viewKeyStruct::fluidNamesString() ); + MultiFluidBase const & fluid = getConstitutiveModel< MultiFluidBase >( subRegion, fluidName ); + arrayView2d< real64 const, multifluid::USD_FLUID > const totalDens = fluid.totalDensity(); + + arrayView2d< real64 const, compflow::USD_COMP > const compFrac = + subRegion.getField< fields::flow::globalCompFraction >(); + arrayView2d< real64, compflow::USD_COMP > const compDens = + subRegion.getField< fields::flow::globalCompDensity >(); + + forAll< parallelDevicePolicy<> >( subRegion.size(), [=] GEOS_HOST_DEVICE ( localIndex const ei ) + { + for( integer ic = 0; ic < numComp; ++ic ) + { + compDens[ei][ic] = totalDens[ei][0] * compFrac[ei][ic]; + } + } ); + } ); + + // with initial component densities defined - check if they need to be corrected to avoid zero diags etc + chopNegativeDensities( domain ); + + // for some reason CUDA does not want the host_device lambda to be defined inside the generic lambda + // I need the exact type of the subRegion for updateSolidflowProperties to work well. + mesh.getElemManager().forElementSubRegions< CellElementSubRegion, + SurfaceElementSubRegion >( regionNames, [&]( localIndex const, + auto & subRegion ) + { + // 4. Initialize/update dependent state quantities + + // 4.1 Update the constitutive models that only depend on + // - the primary variables + // - the fluid constitutive quantities (as they have already been updated) + // We postpone the other constitutive models for now + // In addition, to avoid multiplying permeability/porosity bay netToGross in the assembly kernel, we do it once and for all here + arrayView1d< real64 const > const netToGross = subRegion.template getField< fields::flow::netToGross >(); + CoupledSolidBase const & porousSolid = + getConstitutiveModel< CoupledSolidBase >( subRegion, subRegion.template getReference< string >( viewKeyStruct::solidNamesString() ) ); + PermeabilityBase const & permeabilityModel = + getConstitutiveModel< PermeabilityBase >( subRegion, subRegion.template getReference< string >( viewKeyStruct::permeabilityNamesString() ) ); + permeabilityModel.scaleHorizontalPermeability( netToGross ); + porousSolid.scaleReferencePorosity( netToGross ); + saveConvergedState( subRegion ); // necessary for a meaningful porosity update in sequential schemes + updatePorosityAndPermeability( subRegion ); + updateCompAmount( subRegion ); + updatePhaseVolumeFraction( subRegion ); + + // Now, we initialize and update each constitutive model one by one + + // 4.2 Save the computed porosity into the old porosity + // + // Note: + // - This must be called after updatePorosityAndPermeability + // - This step depends on porosity + string const & solidName = subRegion.template getReference< string >( viewKeyStruct::solidNamesString() ); + CoupledSolidBase const & porousMaterial = getConstitutiveModel< CoupledSolidBase >( subRegion, solidName ); + porousMaterial.initializeState(); + + // 4.3 Initialize/update the relative permeability model using the initial phase volume fraction + // This is needed to handle relative permeability hysteresis + // Also, initialize the fluid model + // + // Note: + // - This must be called after updatePhaseVolumeFraction + // - This step depends on phaseVolFraction + + // initialized phase volume fraction + arrayView2d< real64 const, compflow::USD_PHASE > const phaseVolFrac = + subRegion.template getField< fields::flow::phaseVolumeFraction >(); + + string const & relpermName = subRegion.template getReference< string >( viewKeyStruct::relPermNamesString() ); + RelativePermeabilityBase & relPermMaterial = + getConstitutiveModel< RelativePermeabilityBase >( subRegion, relpermName ); + relPermMaterial.saveConvergedPhaseVolFractionState( phaseVolFrac ); // this needs to happen before calling updateRelPermModel + updateRelPermModel( subRegion ); + relPermMaterial.saveConvergedState(); // this needs to happen after calling updateRelPermModel + + string const & fluidName = subRegion.template getReference< string >( viewKeyStruct::fluidNamesString() ); + MultiFluidBase & fluidMaterial = getConstitutiveModel< MultiFluidBase >( subRegion, fluidName ); + fluidMaterial.initializeState(); + + // 4.4 Then, we initialize/update the capillary pressure model + // + // Note: + // - This must be called after updatePorosityAndPermeability + // - This step depends on porosity and permeability + if( m_hasCapPressure ) + { + // initialized porosity + arrayView2d< real64 const > const porosity = porousMaterial.getPorosity(); + + string const & permName = subRegion.template getReference< string >( viewKeyStruct::permeabilityNamesString() ); + PermeabilityBase const & permeabilityMaterial = + getConstitutiveModel< PermeabilityBase >( subRegion, permName ); + // initialized permeability + arrayView3d< real64 const > const permeability = permeabilityMaterial.permeability(); + + string const & capPressureName = subRegion.template getReference< string >( viewKeyStruct::capPressureNamesString() ); + CapillaryPressureBase const & capPressureMaterial = + getConstitutiveModel< CapillaryPressureBase >( subRegion, capPressureName ); + capPressureMaterial.initializeRockState( porosity, permeability ); // this needs to happen before calling updateCapPressureModel + updateCapPressureModel( subRegion ); + } + + // 4.5 Update the phase mobility + // + // Note: + // - This must be called after updateRelPermModel + // - This step depends phaseRelPerm + updatePhaseMobility( subRegion ); + + } ); + + // 5. Save initial pressure + mesh.getElemManager().forElementSubRegions( regionNames, [&]( localIndex const, + ElementSubRegionBase & subRegion ) + { + arrayView1d< real64 const > const pres = subRegion.getField< fields::flow::pressure >(); + arrayView1d< real64 > const initPres = subRegion.getField< fields::flow::initialPressure >(); + arrayView1d< real64 const > const temp = subRegion.getField< fields::flow::temperature >(); + arrayView1d< real64 > const initTemp = subRegion.template getField< fields::flow::initialTemperature >(); + initPres.setValues< parallelDevicePolicy<> >( pres ); + initTemp.setValues< parallelDevicePolicy<> >( temp ); + } ); +} + +void ImmiscibleMultiphaseFlow::initializePostInitialConditionsPreSubGroups() +{ + GEOS_MARK_FUNCTION; + + FlowSolverBase::initializePostInitialConditionsPreSubGroups(); + + DomainPartition & domain = this->getGroupByPath< DomainPartition >( "/Problem/domain" ); + + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, + MeshLevel & mesh, + arrayView1d< string const > const & regionNames ) + { + FieldIdentifiers fieldsToBeSync; + fieldsToBeSync.addElementFields( { fields::flow::pressure::key(), + fields::flow::globalCompDensity::key() }, + regionNames ); + + CommunicationTools::getInstance().synchronizeFields( fieldsToBeSync, mesh, domain.getNeighbors(), false ); + + mesh.getElemManager().forElementSubRegions< CellElementSubRegion, SurfaceElementSubRegion >( regionNames, + [&]( localIndex const, + auto & subRegion ) + { + // set mass fraction flag on fluid models + string const & fluidName = subRegion.template getReference< string >( viewKeyStruct::fluidNamesString() ); + MultiFluidBase & fluid = getConstitutiveModel< MultiFluidBase >( subRegion, fluidName ); + fluid.setMassFlag( m_useMass ); + + saveConvergedState( subRegion ); // necessary for a meaningful porosity update in sequential schemes + updatePorosityAndPermeability( subRegion ); + + CoupledSolidBase const & porousSolid = + getConstitutiveModel< CoupledSolidBase >( subRegion, + subRegion.template getReference< string >( viewKeyStruct::solidNamesString() ) ); + porousSolid.initializeState(); + } ); + + // Initialize primary variables from applied initial conditions + initializeFluidState( mesh, domain, regionNames ); + + mesh.getElemManager().forElementRegions< SurfaceElementRegion >( regionNames, + [&]( localIndex const, + SurfaceElementRegion & region ) + { + region.forElementSubRegions< FaceElementSubRegion >( [&]( FaceElementSubRegion & subRegion ) + { + subRegion.getWrapper< real64_array >( fields::flow::hydraulicAperture::key() ). + setApplyDefaultValue( region.getDefaultAperture() ); + } ); + } ); + + } ); + + // report to the user if some pore volumes are very small + // note: this function is here because: 1) porosity has been initialized and 2) NTG has been applied + validatePoreVolumes( domain ); +} + +void +ImmiscibleMultiphaseFlow::implicitStepSetup( real64 const & GEOS_UNUSED_PARAM( time_n ), + real64 const & GEOS_UNUSED_PARAM( dt ), + DomainPartition & domain ) +{ + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, + MeshLevel & mesh, + arrayView1d< string const > const & regionNames ) + { + mesh.getElemManager().forElementSubRegions< CellElementSubRegion, + SurfaceElementSubRegion >( regionNames, + [&]( localIndex const, + auto & subRegion ) + { + saveConvergedState( subRegion ); + + // update porosity, permeability + updatePorosityAndPermeability( subRegion ); + // update all fluid properties + updateFluidState( subRegion ); + + // after the update, save the new saturation + arrayView2d< real64 const, compflow::USD_PHASE > const phaseVolFrac = + subRegion.template getField< fields::flow::phaseVolumeFraction >(); + + arrayView2d< real64, compflow::USD_PHASE > const phaseVolFrac_n = + subRegion.template getField< fields::flow::phaseVolumeFraction_n >(); + phaseVolFrac_n.setValues< parallelDevicePolicy<> >( phaseVolFrac ); + + } ); + } ); +} + +void ImmiscibleMultiphaseFlow::assembleSystem( real64 const GEOS_UNUSED_PARAM( time_n ), + real64 const dt, + DomainPartition & domain, + DofManager const & dofManager, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) +{ + GEOS_MARK_FUNCTION; + + assembleAccumulationTerm( domain, + dofManager, + localMatrix, + localRhs ); + + + assembleFluxTerms( dt, + domain, + dofManager, + localMatrix, + localRhs ); +} + +void ImmiscibleMultiphaseFlow::assembleAccumulationTerm( DomainPartition & domain, + DofManager const & dofManager, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) const +{ + GEOS_MARK_FUNCTION; + + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, + MeshLevel const & mesh, + arrayView1d< string const > const & regionNames ) + { + mesh.getElemManager().forElementSubRegions( regionNames, + [&]( localIndex const, + ElementSubRegionBase const & subRegion ) + { + string const dofKey = dofManager.getKey( viewKeyStruct::elemDofFieldString() ); + string const & fluidName = subRegion.getReference< string >( viewKeyStruct::fluidNamesString() ); + string const & solidName = subRegion.getReference< string >( viewKeyStruct::solidNamesString() ); + + MultiFluidBase const & fluid = getConstitutiveModel< MultiFluidBase >( subRegion, fluidName ); + } ); + } ); +} + +void ImmiscibleMultiphaseFlow::applyBoundaryConditions( real64 const time_n, + real64 const dt, + DomainPartition & domain, + DofManager const & dofManager, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) +{ + GEOS_MARK_FUNCTION; + + // apply pressure boundary conditions. + applyDirichletBC( time_n, dt, dofManager, domain, localMatrix.toViewConstSizes(), localRhs.toView() ); + + // apply flux boundary conditions + applySourceFluxBC( time_n, dt, dofManager, domain, localMatrix.toViewConstSizes(), localRhs.toView() ); +} + +namespace +{ +char const bcLogMessage[] = + "ImmiscibleMultiphaseFlow {}: at time {}s, " + "the <{}> boundary condition '{}' is applied to the element set '{}' in subRegion '{}'. " + "\nThe scale of this boundary condition is {} and multiplies the value of the provided function (if any). " + "\nThe total number of target elements (including ghost elements) is {}. " + "\nNote that if this number is equal to zero for all subRegions, the boundary condition will not be applied on this element set."; +} + +void ImmiscibleMultiphaseFlow::applySourceFluxBC( real64 const time, + real64 const dt, + DofManager const & dofManager, + DomainPartition & domain, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) const +{ + GEOS_MARK_FUNCTION; + + FieldSpecificationManager & fsManager = FieldSpecificationManager::getInstance(); + + string const dofKey = dofManager.getKey( viewKeyStruct::elemDofFieldString() ); + + // Step 1: count individual source flux boundary conditions + + std::map< string, localIndex > bcNameToBcId; + localIndex bcCounter = 0; + + fsManager.forSubGroups< SourceFluxBoundaryCondition >( [&] ( SourceFluxBoundaryCondition const & bc ) + { + // collect all the bc names to idx + bcNameToBcId[bc.getName()] = bcCounter; + bcCounter++; + } ); + + if( bcCounter == 0 ) + { + return; + } + + // Step 2: count the set size for each source flux (each source flux may have multiple target sets) + + array1d< globalIndex > bcAllSetsSize( bcNameToBcId.size() ); + + computeSourceFluxSizeScalingFactor( time, + dt, + domain, + bcNameToBcId, + bcAllSetsSize.toView() ); + + // Step 3: we are ready to impose the boundary condition, normalized by the set size + + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, + MeshLevel & mesh, + arrayView1d< string const > const & ) + { + fsManager.apply< ElementSubRegionBase, + SourceFluxBoundaryCondition >( time + dt, + mesh, + SourceFluxBoundaryCondition::catalogName(), + [&]( SourceFluxBoundaryCondition const & fs, + string const & setName, + SortedArrayView< localIndex const > const & targetSet, + ElementSubRegionBase & subRegion, + string const & ) + { + if( fs.getLogLevel() >= 1 && m_nonlinearSolverParameters.m_numNewtonIterations == 0 ) + { + globalIndex const numTargetElems = MpiWrapper::sum< globalIndex >( targetSet.size() ); + GEOS_LOG_RANK_0( GEOS_FMT( bcLogMessage, + getName(), time+dt, fs.getCatalogName(), fs.getName(), + setName, subRegion.getName(), fs.getScale(), numTargetElems ) ); + } + + if( targetSet.size() == 0 ) + { + return; + } + if( !subRegion.hasWrapper( dofKey ) ) + { + if( fs.getLogLevel() >= 1 ) + { + GEOS_LOG_RANK( GEOS_FMT( "{}: trying to apply SourceFlux, but its targetSet named '{}' intersects with non-simulated region named '{}'.", + getDataContext(), setName, subRegion.getName() ) ); + } + return; + } + + arrayView1d< globalIndex const > const dofNumber = subRegion.getReference< array1d< globalIndex > >( dofKey ); + arrayView1d< integer const > const ghostRank = subRegion.ghostRank(); + + // Step 3.1: get the values of the source boundary condition that need to be added to the rhs + // We don't use FieldSpecificationBase::applyConditionToSystem here because we want to account for the row permutation used in the + // compositional solvers + + array1d< globalIndex > dofArray( targetSet.size() ); + array1d< real64 > rhsContributionArray( targetSet.size() ); + arrayView1d< real64 > rhsContributionArrayView = rhsContributionArray.toView(); + localIndex const rankOffset = dofManager.rankOffset(); + + RAJA::ReduceSum< parallelDeviceReduce, real64 > massProd( 0.0 ); + + // note that the dofArray will not be used after this step (simpler to use dofNumber instead) + fs.computeRhsContribution< FieldSpecificationAdd, + parallelDevicePolicy<> >( targetSet.toViewConst(), + time + dt, + dt, + subRegion, + dofNumber, + rankOffset, + localMatrix, + dofArray.toView(), + rhsContributionArrayView, + [] GEOS_HOST_DEVICE ( localIndex const ) + { + return 0.0; + } ); + + // Step 3.2: we are ready to add the right-hand side contributions, taking into account our equation layout + + // get the normalizer + real64 const sizeScalingFactor = bcAllSetsSize[bcNameToBcId.at( fs.getName())]; + + integer const fluidComponentId = fs.getComponent(); + integer const numFluidComponents = m_numComponents; + integer const useTotalMassEquation = m_useTotalMassEquation; + forAll< parallelDevicePolicy<> >( targetSet.size(), [sizeScalingFactor, + targetSet, + rankOffset, + ghostRank, + fluidComponentId, + numFluidComponents, + useTotalMassEquation, + dofNumber, + rhsContributionArrayView, + localRhs, + massProd] GEOS_HOST_DEVICE ( localIndex const a ) + { + // we need to filter out ghosts here, because targetSet may contain them + localIndex const ei = targetSet[a]; + if( ghostRank[ei] >= 0 ) + { + return; + } + + real64 const rhsValue = rhsContributionArrayView[a] / sizeScalingFactor; // scale the contribution by the sizeScalingFactor here! + massProd += rhsValue; + if( useTotalMassEquation > 0 ) + { + // for all "fluid components", we add the value to the total mass balance equation + globalIndex const totalMassBalanceRow = dofNumber[ei] - rankOffset; + localRhs[totalMassBalanceRow] += rhsValue; + if( fluidComponentId < numFluidComponents - 1 ) + { + globalIndex const compMassBalanceRow = totalMassBalanceRow + fluidComponentId + 1; // component mass bal equations are shifted + localRhs[compMassBalanceRow] += rhsValue; + } + } + else + { + globalIndex const compMassBalanceRow = dofNumber[ei] - rankOffset + fluidComponentId; + localRhs[compMassBalanceRow] += rhsValue; + } + } ); + + SourceFluxStatsAggregator::forAllFluxStatWrappers( subRegion, fs.getName(), + [&]( SourceFluxStatsAggregator::WrappedStats & wrapper ) + { + // set the new sub-region statistics for this timestep + array1d< real64 > massProdArr{ m_numComponents }; + massProdArr[fluidComponentId] = massProd.get(); + wrapper.gatherTimeStepStats( time, dt, massProdArr.toViewConst(), targetSet.size() ); + } ); + } ); + } ); +} + +bool ImmiscibleMultiphaseFlow::validateDirichletBC( DomainPartition & domain, + real64 const time ) const +{ + constexpr integer MAX_NC = MultiFluidBase::MAX_NUM_COMPONENTS; + FieldSpecificationManager & fsManager = FieldSpecificationManager::getInstance(); + + bool bcConsistent = true; + + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, + MeshLevel & mesh, + arrayView1d< string const > const & ) + { + // map: regionName -> subRegionName -> setName -> numComps to check pressure/comp are present consistent + map< string, map< string, map< string, ComponentMask< MAX_NC > > > > bcPresCompStatusMap; + // map: regionName -> subRegionName -> setName check to that temperature is present/consistent + map< string, map< string, set< string > > > bcTempStatusMap; + + // 1. Check pressure Dirichlet BCs + fsManager.apply< ElementSubRegionBase >( time, + mesh, + fields::flow::pressure::key(), + [&]( FieldSpecificationBase const &, + string const & setName, + SortedArrayView< localIndex const > const &, + ElementSubRegionBase & subRegion, + string const & ) + { + // Check whether pressure has already been applied to this set + string const & subRegionName = subRegion.getName(); + string const & regionName = subRegion.getParent().getParent().getName(); + + auto & subRegionSetMap = bcPresCompStatusMap[regionName][subRegionName]; + if( subRegionSetMap.count( setName ) > 0 ) + { + bcConsistent = false; + GEOS_WARNING( GEOS_FMT( "Conflicting pressure boundary conditions on set {}/{}/{}", regionName, subRegionName, setName ) ); + } + subRegionSetMap[setName].setNumComp( m_numComponents ); + } ); + } ); + return bcConsistent; +} + +void ImmiscibleMultiphaseFlow::applyDirichletBC( real64 const time_n, + real64 const dt, + DofManager const & dofManager, + DomainPartition & domain, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) const +{ + GEOS_MARK_FUNCTION; + + // Only validate BC at the beginning of Newton loop + if( m_nonlinearSolverParameters.m_numNewtonIterations == 0 ) + { + bool const bcConsistent = validateDirichletBC( domain, time_n + dt ); + GEOS_ERROR_IF( !bcConsistent, GEOS_FMT( "ImmiscibleMultiphaseFlow {}: inconsistent boundary conditions", getDataContext() ) ); + } + + FieldSpecificationManager & fsManager = FieldSpecificationManager::getInstance(); + + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, + MeshLevel & mesh, + arrayView1d< string const > const & ) + { + + // 1. Apply pressure Dirichlet BCs, store in a separate field + applyFieldValue< ElementSubRegionBase >( time_n, dt, mesh, bcLogMessage, + fields::flow::pressure::key(), fields::flow::bcPressure::key() ); + // 2. Apply composition BC (global component fraction) and store them for constitutive call + applyFieldValue< ElementSubRegionBase >( time_n, dt, mesh, bcLogMessage, + fields::flow::globalCompFraction::key(), fields::flow::globalCompFraction::key() ); + // 3. Apply temperature Dirichlet BCs, store in a separate field + if( m_isThermal ) + { + applyFieldValue< ElementSubRegionBase >( time_n, dt, mesh, bcLogMessage, + fields::flow::temperature::key(), fields::flow::bcTemperature::key() ); + } + + globalIndex const rankOffset = dofManager.rankOffset(); + string const dofKey = dofManager.getKey( viewKeyStruct::elemDofFieldString() ); + + // 4. Call constitutive update, back-calculate target global component densities and apply to the system + fsManager.apply< ElementSubRegionBase >( time_n + dt, + mesh, + fields::flow::pressure::key(), + [&] ( FieldSpecificationBase const &, + string const &, + SortedArrayView< localIndex const > const & targetSet, + ElementSubRegionBase & subRegion, + string const & ) + { + string const & fluidName = subRegion.getReference< string >( viewKeyStruct::fluidNamesString() ); + MultiFluidBase & fluid = getConstitutiveModel< MultiFluidBase >( subRegion, fluidName ); + + // in the isothermal case, we use the reservoir temperature to enforce the boundary condition + // in the thermal case, the validation function guarantees that temperature has been provided + string const temperatureKey = m_isThermal ? fields::flow::bcTemperature::key() : fields::flow::temperature::key(); + + arrayView1d< real64 const > const bcPres = + subRegion.getReference< array1d< real64 > >( fields::flow::bcPressure::key() ); + arrayView1d< real64 const > const bcTemp = + subRegion.getReference< array1d< real64 > >( temperatureKey ); + arrayView2d< real64 const, compflow::USD_COMP > const compFrac = + subRegion.getReference< array2d< real64, compflow::LAYOUT_COMP > >( fields::flow::globalCompFraction::key() ); + + constitutiveUpdatePassThru( fluid, [&] ( auto & castedFluid ) + { + using FluidType = TYPEOFREF( castedFluid ); + using ExecPolicy = typename FluidType::exec_policy; + typename FluidType::KernelWrapper fluidWrapper = castedFluid.createKernelWrapper(); + + thermalImmiscibleMultiphaseFlowKernels:: + FluidUpdateKernel:: + launch< ExecPolicy >( targetSet, + fluidWrapper, + bcPres, + bcTemp, + compFrac ); + } ); + + arrayView1d< integer const > const ghostRank = + subRegion.getReference< array1d< integer > >( ObjectManagerBase::viewKeyStruct::ghostRankString() ); + arrayView1d< globalIndex const > const dofNumber = + subRegion.getReference< array1d< globalIndex > >( dofKey ); + arrayView1d< real64 const > const pres = + subRegion.getReference< array1d< real64 > >( fields::flow::pressure::key() ); + arrayView2d< real64 const, compflow::USD_COMP > const compDens = + subRegion.getReference< array2d< real64, compflow::LAYOUT_COMP > >( fields::flow::globalCompDensity::key() ); + arrayView2d< real64 const, multifluid::USD_FLUID > const totalDens = fluid.totalDensity(); + + integer const numComp = m_numComponents; + forAll< parallelDevicePolicy<> >( targetSet.size(), [=] GEOS_HOST_DEVICE ( localIndex const a ) + { + localIndex const ei = targetSet[a]; + if( ghostRank[ei] >= 0 ) + { + return; + } + + globalIndex const dofIndex = dofNumber[ei]; + localIndex const localRow = dofIndex - rankOffset; + real64 rhsValue; + + // 4.1. Apply pressure value to the matrix/rhs + FieldSpecificationEqual::SpecifyFieldValue( dofIndex, + rankOffset, + localMatrix, + rhsValue, + bcPres[ei], + pres[ei] ); + localRhs[localRow] = rhsValue; + + // 4.2. For each component, apply target global density value + for( integer ic = 0; ic < numComp; ++ic ) + { + FieldSpecificationEqual::SpecifyFieldValue( dofIndex + ic + 1, + rankOffset, + localMatrix, + rhsValue, + totalDens[ei][0] * compFrac[ei][ic], + compDens[ei][ic] ); + localRhs[localRow + ic + 1] = rhsValue; + } + } ); + } ); + + // 5. Apply temperature to the system + if( m_isThermal ) + { + fsManager.apply< ElementSubRegionBase >( time_n + dt, + mesh, + fields::flow::temperature::key(), + [&] ( FieldSpecificationBase const &, + string const &, + SortedArrayView< localIndex const > const & targetSet, + ElementSubRegionBase & subRegion, + string const & ) + { + arrayView1d< integer const > const ghostRank = + subRegion.getReference< array1d< integer > >( ObjectManagerBase::viewKeyStruct::ghostRankString() ); + arrayView1d< globalIndex const > const dofNumber = + subRegion.getReference< array1d< globalIndex > >( dofKey ); + arrayView1d< real64 const > const bcTemp = + subRegion.getReference< array1d< real64 > >( fields::flow::bcTemperature::key() ); + arrayView1d< real64 const > const temp = + subRegion.getReference< array1d< real64 > >( fields::flow::temperature::key() ); + + integer const numComp = m_numComponents; + forAll< parallelDevicePolicy<> >( targetSet.size(), [=] GEOS_HOST_DEVICE ( localIndex const a ) + { + localIndex const ei = targetSet[a]; + if( ghostRank[ei] >= 0 ) + { + return; + } + + globalIndex const dofIndex = dofNumber[ei]; + localIndex const localRow = dofIndex - rankOffset; + real64 rhsValue; + + // 4.2. Apply temperature value to the matrix/rhs + FieldSpecificationEqual::SpecifyFieldValue( dofIndex + numComp + 1, + rankOffset, + localMatrix, + rhsValue, + bcTemp[ei], + temp[ei] ); + localRhs[localRow + numComp + 1] = rhsValue; + } ); + } ); + } + } ); +} + + + +void ImmiscibleMultiphaseFlow::resetStateToBeginningOfStep( DomainPartition & domain ) +{ + GEOS_MARK_FUNCTION; + + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, + MeshLevel & mesh, + arrayView1d< string const > const & regionNames ) + { + mesh.getElemManager().forElementSubRegions< CellElementSubRegion, + SurfaceElementSubRegion >( regionNames, + [&]( localIndex const, + auto & subRegion ) + { + arrayView1d< real64 > const & pres = + subRegion.template getField< fields::flow::pressure >(); + arrayView1d< real64 const > const & pres_n = + subRegion.template getField< fields::flow::pressure_n >(); + pres.setValues< parallelDevicePolicy<> >( pres_n ); + + arrayView2d< real64, compflow::USD_COMP > const & compDens = + subRegion.template getField< fields::flow::globalCompDensity >(); + arrayView2d< real64 const, compflow::USD_COMP > const & compDens_n = + subRegion.template getField< fields::flow::globalCompDensity_n >(); + compDens.setValues< parallelDevicePolicy<> >( compDens_n ); + + if( m_isThermal ) + { + arrayView1d< real64 > const & temp = + subRegion.template getField< fields::flow::temperature >(); + arrayView1d< real64 const > const & temp_n = + subRegion.template getField< fields::flow::temperature_n >(); + temp.setValues< parallelDevicePolicy<> >( temp_n ); + } + + // update porosity, permeability + updatePorosityAndPermeability( subRegion ); + // update all fluid properties + updateFluidState( subRegion ); + } ); + } ); +} + +void ImmiscibleMultiphaseFlow::implicitStepComplete( real64 const & time, + real64 const & dt, + DomainPartition & domain ) +{ + // Step 1: save the converged aquifer state + // note: we have to save the aquifer state **before** updating the pressure, + // otherwise the aquifer flux is saved with the wrong pressure time level + saveAquiferConvergedState( time, dt, domain ); + + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, + MeshLevel & mesh, + arrayView1d< string const > const & regionNames ) + { + mesh.getElemManager().forElementSubRegions( regionNames, + [&]( localIndex const, + ElementSubRegionBase & subRegion ) + { + // update deltaPressure + arrayView1d< real64 const > const pres = subRegion.getField< fields::flow::pressure >(); + arrayView1d< real64 const > const initPres = subRegion.getField< fields::flow::initialPressure >(); + arrayView1d< real64 > const deltaPres = subRegion.getField< fields::flow::deltaPressure >(); + isothermalImmiscibleMultiphaseFlowKernels::StatisticsKernel:: + saveDeltaPressure< parallelDevicePolicy<> >( subRegion.size(), pres, initPres, deltaPres ); + + // Step 2: save the converged fluid state + string const & fluidName = subRegion.getReference< string >( viewKeyStruct::fluidNamesString() ); + MultiFluidBase const & fluidMaterial = getConstitutiveModel< MultiFluidBase >( subRegion, fluidName ); + fluidMaterial.saveConvergedState(); + + // Step 3: save the converged solid state + string const & solidName = subRegion.getReference< string >( viewKeyStruct::solidNamesString() ); + CoupledSolidBase const & porousMaterial = getConstitutiveModel< CoupledSolidBase >( subRegion, solidName ); + if( m_keepFlowVariablesConstantDuringInitStep ) + { + porousMaterial.ignoreConvergedState(); // newPorosity <- porosity_n + } + else + { + porousMaterial.saveConvergedState(); // porosity_n <- porosity + } + + // Step 4: save converged state for the relperm model to handle hysteresis + arrayView2d< real64 const, compflow::USD_PHASE > const phaseVolFrac = + subRegion.getField< fields::flow::phaseVolumeFraction >(); + string const & relPermName = subRegion.getReference< string >( viewKeyStruct::relPermNamesString() ); + RelativePermeabilityBase const & relPermMaterial = + getConstitutiveModel< RelativePermeabilityBase >( subRegion, relPermName ); + relPermMaterial.saveConvergedPhaseVolFractionState( phaseVolFrac ); + + // Step 5: if capillary pressure is supported, send the converged porosity and permeability to the capillary pressure model + // note: this is needed when the capillary pressure depends on porosity and permeability (Leverett J-function for instance) + if( m_hasCapPressure ) + { + arrayView2d< real64 const > const porosity = porousMaterial.getPorosity(); + + string const & permName = subRegion.getReference< string >( viewKeyStruct::permeabilityNamesString() ); + PermeabilityBase const & permeabilityMaterial = + getConstitutiveModel< PermeabilityBase >( subRegion, permName ); + arrayView3d< real64 const > const permeability = permeabilityMaterial.permeability(); + + string const & capPressName = subRegion.getReference< string >( viewKeyStruct::capPressureNamesString() ); + CapillaryPressureBase const & capPressureMaterial = + getConstitutiveModel< CapillaryPressureBase >( subRegion, capPressName ); + capPressureMaterial.saveConvergedRockState( porosity, permeability ); + } + } ); + } ); +} + +void ImmiscibleMultiphaseFlow::saveConvergedState( ElementSubRegionBase & subRegion ) const +{ + FlowSolverBase::saveConvergedState( subRegion ); + + arrayView2d< real64 const, compflow::USD_COMP > const & compDens = + subRegion.template getField< fields::flow::globalCompDensity >(); + arrayView2d< real64, compflow::USD_COMP > const & compDens_n = + subRegion.template getField< fields::flow::globalCompDensity_n >(); + compDens_n.setValues< parallelDevicePolicy<> >( compDens ); + + arrayView2d< real64 const, compflow::USD_COMP > const & compAmount = + subRegion.template getField< fields::flow::compAmount >(); + arrayView2d< real64, compflow::USD_COMP > const & compAmount_n = + subRegion.template getField< fields::flow::compAmount_n >(); + compAmount_n.setValues< parallelDevicePolicy<> >( compAmount ); + + if( m_isFixedStressPoromechanicsUpdate ) + { + arrayView2d< real64, compflow::USD_COMP > const & compDens_k = + subRegion.template getField< fields::flow::globalCompDensity_k >(); + compDens_k.setValues< parallelDevicePolicy<> >( compDens ); + } +} + +void ImmiscibleMultiphaseFlow::updateState( DomainPartition & domain ) +{ + GEOS_MARK_FUNCTION; + + real64 maxDeltaPhaseVolFrac = 0.0; + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, + MeshLevel & mesh, + arrayView1d< string const > const & regionNames ) + { + mesh.getElemManager().forElementSubRegions< CellElementSubRegion, + SurfaceElementSubRegion >( regionNames, [&]( localIndex const, + auto & subRegion ) + { + // update porosity, permeability, and solid internal energy + updatePorosityAndPermeability( subRegion ); + // update all fluid properties + real64 const deltaPhaseVolFrac = updateFluidState( subRegion ); + maxDeltaPhaseVolFrac = LvArray::math::max( maxDeltaPhaseVolFrac, deltaPhaseVolFrac ); + // for thermal, update solid internal energy + if( m_isThermal ) + { + updateSolidInternalEnergyModel( subRegion ); + updateEnergy( subRegion ); + } + } ); + } ); + + maxDeltaPhaseVolFrac = MpiWrapper::max( maxDeltaPhaseVolFrac ); + + GEOS_LOG_LEVEL_RANK_0( 1, GEOS_FMT( " {}: Max phase volume fraction change = {}", getName(), fmt::format( "{:.{}f}", maxDeltaPhaseVolFrac, 4 ) ) ); +} + +real64 ImmiscibleMultiphaseFlow::setNextDt( const geos::real64 & currentDt, geos::DomainPartition & domain ) +{ + return SolverBase::setNextDt( currentDt, domain ); +} + +REGISTER_CATALOG_ENTRY( SolverBase, ImmiscibleMultiphaseFlow, string const &, Group * const ) + +} // namespace geos diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp new file mode 100644 index 00000000000..e2e7b6ef838 --- /dev/null +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp @@ -0,0 +1,389 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * SPDX-License-Identifier: LGPL-2.1-only + * + * Copyright (c) 2016-2024 Lawrence Livermore National Security LLC + * Copyright (c) 2018-2024 Total, S.A + * Copyright (c) 2018-2024 The Board of Trustees of the Leland Stanford Junior University + * Copyright (c) 2018-2024 Chevron + * Copyright (c) 2019- GEOS/GEOSX Contributors + * All rights reserved + * + * See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details. + * ------------------------------------------------------------------------------------------------------------ + */ + +/** + * @file ImmiscibleMultiphaseFlow.hpp + */ + +#ifndef GEOS_PHYSICSSOLVERS_FLUIDFLOW_IMMISCIBLEMULTIPHASEFLOW_HPP_ +#define GEOS_PHYSICSSOLVERS_FLUIDFLOW_IMMISCIBLEMULTIPHASEFLOW_HPP_ + +#include "physicsSolvers/fluidFlow/FlowSolverBase.hpp" +#include "fieldSpecification/FieldSpecificationManager.hpp" + +namespace geos +{ + +//START_SPHINX_INCLUDE_00 +/** + * @class ImmiscibleMultiphaseFlow + * + * An Immiscible multiphase flow solver + */ +class ImmiscibleMultiphaseFlow : public FlowSolverBase +{ +public: + + /** + * @brief main constructor for Group Objects + * @param name the name of this instantiation of Group in the repository + * @param parent the parent group of this instantiation of Group + */ + ImmiscibleMultiphaseFlow( const string & name, + Group * const parent ); + + /// deleted default constructor + ImmiscibleMultiphaseFlow() = delete; + + /// deleted copy constructor + ImmiscibleMultiphaseFlow( ImmiscibleMultiphaseFlow const & ) = delete; + + /// default move constructor + ImmiscibleMultiphaseFlow( ImmiscibleMultiphaseFlow && ) = default; + + /// deleted assignment operator + ImmiscibleMultiphaseFlow & operator=( ImmiscibleMultiphaseFlow const & ) = delete; + + /// deleted move operator + ImmiscibleMultiphaseFlow & operator=( ImmiscibleMultiphaseFlow && ) = delete; + + /** + * @brief default destructor + */ + virtual ~ImmiscibleMultiphaseFlow() override = default; + +//START_SPHINX_INCLUDE_01 + + virtual void registerDataOnMesh( Group & meshBodies ) override; + + /** + * @defgroup Solver Interface Functions + * + * These functions provide the primary interface that is required for derived classes + */ + /**@{*/ + + virtual void + implicitStepSetup( real64 const & time_n, + real64 const & dt, + DomainPartition & domain ) override; + + virtual void + assembleSystem( real64 const time_n, + real64 const dt, + DomainPartition & domain, + DofManager const & dofManager, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) override; + + virtual void + applyBoundaryConditions( real64 const time_n, + real64 const dt, + DomainPartition & domain, + DofManager const & dofManager, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) override; + + virtual void + resetStateToBeginningOfStep( DomainPartition & domain ) override; + + virtual void + implicitStepComplete( real64 const & time, + real64 const & dt, + DomainPartition & domain ) override; + + /** + * @brief Recompute phase volume fractions (saturations) from constitutive and primary variables + * @param dataGroup the group storing the required fields + */ + real64 updatePhaseVolumeFraction( ObjectManagerBase & dataGroup ) const; + + /** + * @brief Update all relevant fluid models using current values of pressure and composition + * @param dataGroup the group storing the required fields + */ + void updateFluidModel( ObjectManagerBase & dataGroup ) const; + + /** + * @brief Update all relevant relperm models using current values of phase volume fraction + * @param dataGroup the group storing the required fields + */ + void updateRelPermModel( ObjectManagerBase & dataGroup ) const; + + /** + * @brief Update all relevant capillary pressure models using current values of phase volume fraction + * @param dataGroup the group storing the required fields + */ + void updateCapPressureModel( ObjectManagerBase & dataGroup ) const; + + + + + /** + * @brief Recompute phase mobility from constitutive and primary variables + * @param dataGroup the group storing the required field + */ + virtual void updatePhaseMobility( ObjectManagerBase & dataGroup ) const = 0; + + real64 updateFluidState( ElementSubRegionBase & subRegion ) const; + + virtual void saveConvergedState( ElementSubRegionBase & subRegion ) const override final; + + virtual void saveSequentialIterationState( DomainPartition & domain ) override final; + + virtual void updateState( DomainPartition & domain ) override final; + + + /** + * @brief Getter for the number of fluid phases + * @return the number of phases + */ + integer numFluidPhases() const { return m_numPhases; } + + /** + * @brief assembles the accumulation and volume balance terms for all cells + * @param time_n previous time value + * @param dt time step + * @param domain the physical domain object + * @param dofManager degree-of-freedom manager associated with the linear system + * @param localMatrix the system matrix + * @param localRhs the system right-hand side vector + */ + void assembleAccumulationAndVolumeBalanceTerms( DomainPartition & domain, + DofManager const & dofManager, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) const; + + /** + * @brief assembles the flux terms for all cells + * @param time_n previous time value + * @param dt time step + * @param domain the physical domain object + * @param dofManager degree-of-freedom manager associated with the linear system + * @param matrix the system matrix + * @param rhs the system right-hand side vector + */ + virtual void + assembleFluxTerms( real64 const dt, + DomainPartition const & domain, + DofManager const & dofManager, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) const = 0; + /** + * @brief Initialize all variables from initial conditions + * @param domain the domain containing the mesh and fields + * + * Initialize all variables from initial conditions. This calculating primary variable values + * from prescribed intermediate values (i.e. global densities from global fractions) + * and any applicable hydrostatic equilibration of the domain + */ + void initializeFluidState( MeshLevel & mesh, DomainPartition & domain, arrayView1d< string const > const & regionNames ); + + /** + * @brief Compute the hydrostatic equilibrium using the compositions and temperature input tables + */ + void computeHydrostaticEquilibrium(); + + /** + * @brief Function to perform the Application of Dirichlet type BC's + * @param time current time + * @param dt time step + * @param dofManager degree-of-freedom manager associated with the linear system + * @param domain the domain + * @param localMatrix local system matrix + * @param localRhs local system right-hand side vector + */ + void applyDirichletBC( real64 const time, + real64 const dt, + DofManager const & dofManager, + DomainPartition & domain, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) const; + + /** + * @brief Apply source flux boundary conditions to the system + * @param time current time + * @param dt time step + * @param dofManager degree-of-freedom manager associated with the linear system + * @param domain the domain + * @param localMatrix local system matrix + * @param localRhs local system right-hand side vector + */ + void applySourceFluxBC( real64 const time, + real64 const dt, + DofManager const & dofManager, + DomainPartition & domain, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) const; + + /** + * @brief Apply aquifer boundary conditions to the system + * @param time current time + * @param dt time step + * @param dofManager degree-of-freedom manager associated with the linear system + * @param domain the domain + * @param localMatrix local system matrix + * @param localRhs local system right-hand side vector + */ + virtual void applyAquiferBC( real64 const time, + real64 const dt, + DofManager const & dofManager, + DomainPartition & domain, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) const = 0; + + /** + * @brief Function to fix the initial state during the initialization step in coupled problems + * @param[in] time current time + * @param[in] dt time step + * @param[in] dofManager degree-of-freedom manager associated with the linear system + * @param[in] domain the domain + * @param[in] localMatrix local system matrix + * @param[in] localRhs local system right-hand side vector + * @detail This function is meant to be called when the flag m_keepFlowVariablesConstantDuringInitStep is on + * The main use case is the initialization step in coupled problems during which we solve an elastic problem for a fixed pressure + */ + void keepFlowVariablesConstantDuringInitStep( real64 const time, + real64 const dt, + DofManager const & dofManager, + DomainPartition & domain, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) const; + + + /** + * @brief Sets all the negative component densities (if any) to zero. + * @param domain the physical domain object + */ + void chopNegativeDensities( DomainPartition & domain ); + + virtual real64 setNextDtBasedOnStateChange( real64 const & currentDt, + DomainPartition & domain ) override; + + void computeCFLNumbers( DomainPartition & domain, real64 const & dt, real64 & maxPhaseCFL, real64 & maxCompCFL ); + + /** + * @brief function to set the next time step size + * @param[in] currentDt the current time step size + * @param[in] domain the domain object + * @return the prescribed time step size + */ + real64 setNextDt( real64 const & currentDt, + DomainPartition & domain ) override; + + virtual real64 setNextDtBasedOnCFL( real64 const & currentDt, + DomainPartition & domain ) override; + + virtual void initializePostInitialConditionsPreSubGroups() override; + + integer useSimpleAccumulation() const { return m_useSimpleAccumulation; } + + integer useTotalMassEquation() const { return m_useTotalMassEquation; } + + virtual bool checkSequentialSolutionIncrements( DomainPartition & domain ) const override; + +protected: + + virtual void postInputInitialization() override; + + virtual void initializePreSubGroups() override; + + + /** + * @brief Utility function that checks the consistency of the constitutive models + * @param[in] domain the domain partition + * This function will produce an error if one of the constitutive models + * (fluid, relperm) is incompatible with the reference fluid model. + */ + void validateConstitutiveModels( DomainPartition const & domain ) const; + + /** + * @brief Initialize the aquifer boundary condition (gravity vector, water phase index) + * @param[in] cm reference to the global constitutive model manager + */ + void initializeAquiferBC( constitutive::ConstitutiveManager const & cm ) const; + + /** + * @brief Utility function that encapsulates the call to FieldSpecificationBase::applyFieldValue in BC application + * @param[in] time_n the time at the beginning of the step + * @param[in] dt the time step + * @param[in] mesh the mesh level object + * @param[in] logMessage the log message issued by the solver if the bc is called + * @param[in] fieldKey the key of the field specified in the xml file + * @param[in] boundaryFieldKey the key of the boundary field + */ + template< typename OBJECT_TYPE > + void applyFieldValue( real64 const & time_n, + real64 const & dt, + MeshLevel & mesh, + char const logMessage[], + string const fieldKey, + string const boundaryFieldKey ) const; + + /// the max number of fluid phases + integer m_numPhases; + + /// flag to determine whether or not to apply capillary pressure + integer m_hasCapPressure; + + /// the targeted CFL for timestep + real64 m_targetFlowCFL; + +private: + + virtual void setConstitutiveNames( ElementSubRegionBase & subRegion ) const override; + +}; + +template< typename OBJECT_TYPE > +void ImmiscibleMultiphaseFlow::applyFieldValue( real64 const & time_n, + real64 const & dt, + MeshLevel & mesh, + char const logMessage[], + string const fieldKey, + string const boundaryFieldKey ) const +{ + FieldSpecificationManager & fsManager = FieldSpecificationManager::getInstance(); + + fsManager.apply< OBJECT_TYPE >( time_n + dt, + mesh, + fieldKey, + [&]( FieldSpecificationBase const & fs, + string const & setName, + SortedArrayView< localIndex const > const & lset, + OBJECT_TYPE & targetGroup, + string const & ) + { + if( fs.getLogLevel() >= 1 && m_nonlinearSolverParameters.m_numNewtonIterations == 0 ) + { + globalIndex const numTargetElems = MpiWrapper::sum< globalIndex >( lset.size() ); + GEOS_LOG_RANK_0( GEOS_FMT( logMessage, + getName(), time_n+dt, fs.getCatalogName(), fs.getName(), + setName, targetGroup.getName(), fs.getScale(), numTargetElems ) ); + } + + // Specify the bc value of the field + fs.applyFieldValue< FieldSpecificationEqual, + parallelDevicePolicy<> >( lset, + time_n + dt, + targetGroup, + boundaryFieldKey ); + } ); +} + + +} // namespace geos + +#endif //GEOS_PHYSICSSOLVERS_FLUIDFLOW_IMMISCIBLEMULTIPHASEFLOW_HPP_ From 22aed17ce1322055d2408ae72c56a88d928de1d6 Mon Sep 17 00:00:00 2001 From: Matteo Cusini Date: Fri, 26 Jul 2024 16:47:44 -0700 Subject: [PATCH 002/102] catalog name, register and cmakelist. --- .../physicsSolvers/fluidFlow/CMakeLists.txt | 2 + .../fluidFlow/ImmiscibleMultiphaseFlow.cpp | 27 +++-- .../fluidFlow/ImmiscibleMultiphaseFlow.hpp | 103 ++---------------- 3 files changed, 30 insertions(+), 102 deletions(-) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/CMakeLists.txt b/src/coreComponents/physicsSolvers/fluidFlow/CMakeLists.txt index ee3263c50b2..65e1180ffe2 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/CMakeLists.txt +++ b/src/coreComponents/physicsSolvers/fluidFlow/CMakeLists.txt @@ -7,6 +7,7 @@ set( physicsSolvers_headers fluidFlow/IsothermalCompositionalMultiphaseBaseKernels.hpp fluidFlow/ThermalCompositionalMultiphaseBaseKernels.hpp fluidFlow/CompositionalMultiphaseFVM.hpp + fluidFlow/ImmiscibleMultiphaseFlow.hpp fluidFlow/IsothermalCompositionalMultiphaseFVMKernels.hpp fluidFlow/IsothermalCompositionalMultiphaseFVMKernelUtilities.hpp fluidFlow/ThermalCompositionalMultiphaseFVMKernels.hpp @@ -59,6 +60,7 @@ set( physicsSolvers_sources fluidFlow/CompositionalMultiphaseBase.cpp fluidFlow/CompositionalMultiphaseFVM.cpp fluidFlow/CompositionalMultiphaseStatistics.cpp + fluidFlow/ImmiscibleMultiphaseFlow.cpp fluidFlow/IsothermalCompositionalMultiphaseFVMKernels.cpp fluidFlow/CompositionalMultiphaseHybridFVM.cpp fluidFlow/CompositionalMultiphaseHybridFVMKernels.cpp diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp index db3a431bcd0..74e4ba7ad14 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp @@ -238,16 +238,16 @@ void ImmiscibleMultiphaseFlow::updateRelPermModel( ObjectManagerBase & dataGroup string const & relPermName = dataGroup.getReference< string >( viewKeyStruct::relPermNamesString() ); RelativePermeabilityBase & relPerm = getConstitutiveModel< RelativePermeabilityBase >( dataGroup, relPermName ); - constitutive::constitutiveUpdatePassThru( relPerm, [&] ( auto & castedRelPerm ) - { - typename TYPEOFREF( castedRelPerm ) ::KernelWrapper relPermWrapper = castedRelPerm.createKernelWrapper(); - - isothermalImmiscibleMultiphaseFlowKernels:: - RelativePermeabilityUpdateKernel:: - launch< parallelDevicePolicy<> >( dataGroup.size(), - relPermWrapper, - phaseVolFrac ); - } ); + // constitutive::constitutiveUpdatePassThru( relPerm, [&] ( auto & castedRelPerm ) + // { + // typename TYPEOFREF( castedRelPerm ) ::KernelWrapper relPermWrapper = castedRelPerm.createKernelWrapper(); + + // isothermalImmiscibleMultiphaseFlowKernels:: + // RelativePermeabilityUpdateKernel:: + // launch< parallelDevicePolicy<> >( dataGroup.size(), + // relPermWrapper, + // phaseVolFrac ); + // } ); } void ImmiscibleMultiphaseFlow::updateCapPressureModel( ObjectManagerBase & dataGroup ) const @@ -565,6 +565,13 @@ void ImmiscibleMultiphaseFlow::assembleAccumulationTerm( DomainPartition & domai } ); } +void ImmiscibleMultiphaseFlow::assembleFluxTerms( real64 const dt, + DomainPartition const & domain, + DofManager const & dofManager, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) const +{} + void ImmiscibleMultiphaseFlow::applyBoundaryConditions( real64 const time_n, real64 const dt, DomainPartition & domain, diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp index e2e7b6ef838..ec5c2605c20 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp @@ -63,8 +63,15 @@ class ImmiscibleMultiphaseFlow : public FlowSolverBase * @brief default destructor */ virtual ~ImmiscibleMultiphaseFlow() override = default; - -//START_SPHINX_INCLUDE_01 + /** + * @brief name of the solver in the object catalog + * @return string that contains the catalog name to generate a new object through the object catalog. + */ + static string catalogName() { return "ImmiscibleMultiphaseFlow"; } + /** + * @copydoc SolverBase::getCatalogName() + */ + string getCatalogName() const override { return catalogName(); } virtual void registerDataOnMesh( Group & meshBodies ) override; @@ -104,12 +111,6 @@ class ImmiscibleMultiphaseFlow : public FlowSolverBase real64 const & dt, DomainPartition & domain ) override; - /** - * @brief Recompute phase volume fractions (saturations) from constitutive and primary variables - * @param dataGroup the group storing the required fields - */ - real64 updatePhaseVolumeFraction( ObjectManagerBase & dataGroup ) const; - /** * @brief Update all relevant fluid models using current values of pressure and composition * @param dataGroup the group storing the required fields @@ -129,8 +130,6 @@ class ImmiscibleMultiphaseFlow : public FlowSolverBase void updateCapPressureModel( ObjectManagerBase & dataGroup ) const; - - /** * @brief Recompute phase mobility from constitutive and primary variables * @param dataGroup the group storing the required field @@ -141,7 +140,6 @@ class ImmiscibleMultiphaseFlow : public FlowSolverBase virtual void saveConvergedState( ElementSubRegionBase & subRegion ) const override final; - virtual void saveSequentialIterationState( DomainPartition & domain ) override final; virtual void updateState( DomainPartition & domain ) override final; @@ -161,7 +159,7 @@ class ImmiscibleMultiphaseFlow : public FlowSolverBase * @param localMatrix the system matrix * @param localRhs the system right-hand side vector */ - void assembleAccumulationAndVolumeBalanceTerms( DomainPartition & domain, + void assembleAccumulationTerm( DomainPartition & domain, DofManager const & dofManager, CRSMatrixView< real64, globalIndex const > const & localMatrix, arrayView1d< real64 > const & localRhs ) const; @@ -180,7 +178,7 @@ class ImmiscibleMultiphaseFlow : public FlowSolverBase DomainPartition const & domain, DofManager const & dofManager, CRSMatrixView< real64, globalIndex const > const & localMatrix, - arrayView1d< real64 > const & localRhs ) const = 0; + arrayView1d< real64 > const & localRhs ) const override final; /** * @brief Initialize all variables from initial conditions * @param domain the domain containing the mesh and fields @@ -191,11 +189,6 @@ class ImmiscibleMultiphaseFlow : public FlowSolverBase */ void initializeFluidState( MeshLevel & mesh, DomainPartition & domain, arrayView1d< string const > const & regionNames ); - /** - * @brief Compute the hydrostatic equilibrium using the compositions and temperature input tables - */ - void computeHydrostaticEquilibrium(); - /** * @brief Function to perform the Application of Dirichlet type BC's * @param time current time @@ -227,53 +220,6 @@ class ImmiscibleMultiphaseFlow : public FlowSolverBase DomainPartition & domain, CRSMatrixView< real64, globalIndex const > const & localMatrix, arrayView1d< real64 > const & localRhs ) const; - - /** - * @brief Apply aquifer boundary conditions to the system - * @param time current time - * @param dt time step - * @param dofManager degree-of-freedom manager associated with the linear system - * @param domain the domain - * @param localMatrix local system matrix - * @param localRhs local system right-hand side vector - */ - virtual void applyAquiferBC( real64 const time, - real64 const dt, - DofManager const & dofManager, - DomainPartition & domain, - CRSMatrixView< real64, globalIndex const > const & localMatrix, - arrayView1d< real64 > const & localRhs ) const = 0; - - /** - * @brief Function to fix the initial state during the initialization step in coupled problems - * @param[in] time current time - * @param[in] dt time step - * @param[in] dofManager degree-of-freedom manager associated with the linear system - * @param[in] domain the domain - * @param[in] localMatrix local system matrix - * @param[in] localRhs local system right-hand side vector - * @detail This function is meant to be called when the flag m_keepFlowVariablesConstantDuringInitStep is on - * The main use case is the initialization step in coupled problems during which we solve an elastic problem for a fixed pressure - */ - void keepFlowVariablesConstantDuringInitStep( real64 const time, - real64 const dt, - DofManager const & dofManager, - DomainPartition & domain, - CRSMatrixView< real64, globalIndex const > const & localMatrix, - arrayView1d< real64 > const & localRhs ) const; - - - /** - * @brief Sets all the negative component densities (if any) to zero. - * @param domain the physical domain object - */ - void chopNegativeDensities( DomainPartition & domain ); - - virtual real64 setNextDtBasedOnStateChange( real64 const & currentDt, - DomainPartition & domain ) override; - - void computeCFLNumbers( DomainPartition & domain, real64 const & dt, real64 & maxPhaseCFL, real64 & maxCompCFL ); - /** * @brief function to set the next time step size * @param[in] currentDt the current time step size @@ -283,38 +229,14 @@ class ImmiscibleMultiphaseFlow : public FlowSolverBase real64 setNextDt( real64 const & currentDt, DomainPartition & domain ) override; - virtual real64 setNextDtBasedOnCFL( real64 const & currentDt, - DomainPartition & domain ) override; - virtual void initializePostInitialConditionsPreSubGroups() override; - integer useSimpleAccumulation() const { return m_useSimpleAccumulation; } - - integer useTotalMassEquation() const { return m_useTotalMassEquation; } - - virtual bool checkSequentialSolutionIncrements( DomainPartition & domain ) const override; - protected: virtual void postInputInitialization() override; virtual void initializePreSubGroups() override; - - /** - * @brief Utility function that checks the consistency of the constitutive models - * @param[in] domain the domain partition - * This function will produce an error if one of the constitutive models - * (fluid, relperm) is incompatible with the reference fluid model. - */ - void validateConstitutiveModels( DomainPartition const & domain ) const; - - /** - * @brief Initialize the aquifer boundary condition (gravity vector, water phase index) - * @param[in] cm reference to the global constitutive model manager - */ - void initializeAquiferBC( constitutive::ConstitutiveManager const & cm ) const; - /** * @brief Utility function that encapsulates the call to FieldSpecificationBase::applyFieldValue in BC application * @param[in] time_n the time at the beginning of the step @@ -338,9 +260,6 @@ class ImmiscibleMultiphaseFlow : public FlowSolverBase /// flag to determine whether or not to apply capillary pressure integer m_hasCapPressure; - /// the targeted CFL for timestep - real64 m_targetFlowCFL; - private: virtual void setConstitutiveNames( ElementSubRegionBase & subRegion ) const override; From fd51d9191444e8c54c0d02a24f2a9f55421c7c1b Mon Sep 17 00:00:00 2001 From: Matteo Cusini Date: Mon, 29 Jul 2024 15:45:00 -0700 Subject: [PATCH 003/102] fix fields. --- src/coreComponents/common/DataLayouts.hpp | 29 ++ .../fluidFlow/ImmiscibleMultiphaseFlow.cpp | 305 +----------------- .../fluidFlow/ImmiscibleMultiphaseFlow.hpp | 13 +- .../ImmiscibleMultiphaseFlowFields.hpp | 93 ++++++ 4 files changed, 135 insertions(+), 305 deletions(-) create mode 100644 src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlowFields.hpp diff --git a/src/coreComponents/common/DataLayouts.hpp b/src/coreComponents/common/DataLayouts.hpp index 38d149a1938..d1c892754ee 100644 --- a/src/coreComponents/common/DataLayouts.hpp +++ b/src/coreComponents/common/DataLayouts.hpp @@ -205,6 +205,35 @@ static constexpr int STIFFNESS_USD = LvArray::typeManipulation::getStrideOneDime } // namespace solid + +namespace immiscibleFlow +{ +#if defined( GEOS_USE_DEVICE ) + +/// Phase property array layout +using LAYOUT_PHASE = RAJA::PERM_JI; + +/// Phase property array layout +using LAYOUT_PHASE_DS = RAJA::PERM_JKI; + +#else + +/// Phase property array layout +using LAYOUT_PHASE = RAJA::PERM_IJ; + +/// Phase property array layout +using LAYOUT_PHASE_DS = RAJA::PERM_IJK; + +#endif + +/// Phase property unit stride dimension +static constexpr int USD_PHASE = LvArray::typeManipulation::getStrideOneDimension( LAYOUT_PHASE{} ); + +/// Phase property compositional derivative unit stride dimension +static constexpr int USD_PHASE_DS = LvArray::typeManipulation::getStrideOneDimension( LAYOUT_PHASE_DS{} ); + +} // namespace immiscibleFlow + namespace compflow { diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp index 74e4ba7ad14..0c7932f7ba2 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp @@ -19,6 +19,8 @@ #include "ImmiscibleMultiphaseFlow.hpp" + +#include "ImmiscibleMultiphaseFlowFields.hpp" #include "constitutive/ConstitutiveManager.hpp" #include "constitutive/capillaryPressure/CapillaryPressureFields.hpp" #include "constitutive/capillaryPressure/capillaryPressureSelector.hpp" @@ -33,6 +35,7 @@ namespace geos using namespace dataRepository; using namespace constitutive; +using namespace fields:flow:immiscibleFlow; ImmiscibleMultiphaseFlow::ImmiscibleMultiphaseFlow( const string & name, Group * const parent ) @@ -106,15 +109,14 @@ void ImmiscibleMultiphaseFlow::registerDataOnMesh( Group & meshBodies ) InputError ); } - - string const & fluidName = subRegion.getReference< string >( viewKeyStruct::fluidNamesString() ); - MultiFluidBase const & fluid = getConstitutiveModel< MultiFluidBase >( subRegion, fluidName ); - // The resizing of the arrays needs to happen here, before the call to initializePreSubGroups, // to make sure that the dimensions are properly set before the timeHistoryOutput starts its initialization. subRegion.registerField< phaseVolumeFraction >( getName() ). setDimLabels( 1, fluid.phaseNames() ). reference().resizeDimension< 1 >( m_numPhases ); + + subRegion.registerField< phaseVolumeFraction_n >( getName() ). + reference().resizeDimension< 1 >( m_numPhases ); subRegion.registerField< phaseMobility >( getName() ). setDimLabels( 1, fluid.phaseNames() ). @@ -123,29 +125,17 @@ void ImmiscibleMultiphaseFlow::registerDataOnMesh( Group & meshBodies ) subRegion.registerField< dPhaseMobility >( getName() ). reference().resizeDimension< 1, 2 >( m_numPhases, m_numPhases ); // dP, dT, dC - subRegion.registerField< phaseVolumeFraction_n >( getName() ). - reference().resizeDimension< 1 >( m_numPhases ); } ); FaceManager & faceManager = mesh.getFaceManager(); { faceManager.registerField< totalMassFlux >( getName() ); - // TODO: add conditional registration later, this is only needed when there is a face-based Dirichlet BC - faceManager.registerField< facePressure >( getName() ); - faceManager.registerField< faceTemperature >( getName() ); } } ); } void ImmiscibleMultiphaseFlow::setConstitutiveNames( ElementSubRegionBase & subRegion ) const { - string & fluidName = subRegion.getReference< string >( viewKeyStruct::fluidNamesString() ); - fluidName = getConstitutiveName< MultiFluidBase >( subRegion ); - GEOS_THROW_IF( fluidName.empty(), - GEOS_FMT( "{}: Fluid model not found on subregion {}", - getDataContext(), subRegion.getDataContext() ), - InputError ); - string & relPermName = subRegion.registerWrapper< string >( viewKeyStruct::relPermNamesString() ). setPlotLevel( PlotLevel::NOPLOT ). setRestartFlags( RestartFlags::NO_WRITE ). @@ -192,7 +182,6 @@ void ImmiscibleMultiphaseFlow::validateConstitutiveModels( DomainPartition const GEOS_MARK_FUNCTION; ConstitutiveManager const & cm = domain.getConstitutiveManager(); - MultiFluidBase const & referenceFluid = cm.getConstitutiveRelation< MultiFluidBase >( m_referenceFluidModelName ); forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, MeshLevel const & mesh, @@ -203,16 +192,9 @@ void ImmiscibleMultiphaseFlow::validateConstitutiveModels( DomainPartition const [&]( localIndex const, ElementSubRegionBase const & subRegion ) { - - string const & fluidName = subRegion.getReference< string >( viewKeyStruct::fluidNamesString() ); - MultiFluidBase const & fluid = getConstitutiveModel< MultiFluidBase >( subRegion, fluidName ); - compareMultiphaseModels( fluid, referenceFluid ); - compareMulticomponentModels( fluid, referenceFluid ); - string const & relpermName = subRegion.getReference< string >( viewKeyStruct::relPermNamesString() ); RelativePermeabilityBase const & relPerm = getConstitutiveModel< RelativePermeabilityBase >( subRegion, relpermName ); compareMultiphaseModels( relPerm, referenceFluid ); - } ); } ); } @@ -223,9 +205,6 @@ void ImmiscibleMultiphaseFlow::updateFluidModel( ObjectManagerBase & dataGroup ) arrayView1d< real64 const > const pres = dataGroup.getField< fields::flow::pressure >(); arrayView1d< real64 const > const temp = dataGroup.getField< fields::flow::temperature >(); - - string const & fluidName = dataGroup.getReference< string >( viewKeyStruct::fluidNamesString() ); - MultiFluidBase & fluid = getConstitutiveModel< MultiFluidBase >( dataGroup, fluidName ); } void ImmiscibleMultiphaseFlow::updateRelPermModel( ObjectManagerBase & dataGroup ) const @@ -301,24 +280,6 @@ void ImmiscibleMultiphaseFlow::initializeFluidState( MeshLevel & mesh, // Initialize constitutive state to get fluid density. updateFluidModel( subRegion ); - // 3. Back-calculate global component densities from fractions and total fluid density - // in order to initialize the primary solution variables - string const & fluidName = subRegion.getReference< string >( viewKeyStruct::fluidNamesString() ); - MultiFluidBase const & fluid = getConstitutiveModel< MultiFluidBase >( subRegion, fluidName ); - arrayView2d< real64 const, multifluid::USD_FLUID > const totalDens = fluid.totalDensity(); - - arrayView2d< real64 const, compflow::USD_COMP > const compFrac = - subRegion.getField< fields::flow::globalCompFraction >(); - arrayView2d< real64, compflow::USD_COMP > const compDens = - subRegion.getField< fields::flow::globalCompDensity >(); - - forAll< parallelDevicePolicy<> >( subRegion.size(), [=] GEOS_HOST_DEVICE ( localIndex const ei ) - { - for( integer ic = 0; ic < numComp; ++ic ) - { - compDens[ei][ic] = totalDens[ei][0] * compFrac[ei][ic]; - } - } ); } ); // with initial component densities defined - check if they need to be corrected to avoid zero diags etc @@ -379,10 +340,6 @@ void ImmiscibleMultiphaseFlow::initializeFluidState( MeshLevel & mesh, updateRelPermModel( subRegion ); relPermMaterial.saveConvergedState(); // this needs to happen after calling updateRelPermModel - string const & fluidName = subRegion.template getReference< string >( viewKeyStruct::fluidNamesString() ); - MultiFluidBase & fluidMaterial = getConstitutiveModel< MultiFluidBase >( subRegion, fluidName ); - fluidMaterial.initializeState(); - // 4.4 Then, we initialize/update the capillary pressure model // // Note: @@ -451,11 +408,6 @@ void ImmiscibleMultiphaseFlow::initializePostInitialConditionsPreSubGroups() [&]( localIndex const, auto & subRegion ) { - // set mass fraction flag on fluid models - string const & fluidName = subRegion.template getReference< string >( viewKeyStruct::fluidNamesString() ); - MultiFluidBase & fluid = getConstitutiveModel< MultiFluidBase >( subRegion, fluidName ); - fluid.setMassFlag( m_useMass ); - saveConvergedState( subRegion ); // necessary for a meaningful porosity update in sequential schemes updatePorosityAndPermeability( subRegion ); @@ -559,8 +511,6 @@ void ImmiscibleMultiphaseFlow::assembleAccumulationTerm( DomainPartition & domai string const dofKey = dofManager.getKey( viewKeyStruct::elemDofFieldString() ); string const & fluidName = subRegion.getReference< string >( viewKeyStruct::fluidNamesString() ); string const & solidName = subRegion.getReference< string >( viewKeyStruct::solidNamesString() ); - - MultiFluidBase const & fluid = getConstitutiveModel< MultiFluidBase >( subRegion, fluidName ); } ); } ); } @@ -765,222 +715,6 @@ void ImmiscibleMultiphaseFlow::applySourceFluxBC( real64 const time, } ); } -bool ImmiscibleMultiphaseFlow::validateDirichletBC( DomainPartition & domain, - real64 const time ) const -{ - constexpr integer MAX_NC = MultiFluidBase::MAX_NUM_COMPONENTS; - FieldSpecificationManager & fsManager = FieldSpecificationManager::getInstance(); - - bool bcConsistent = true; - - forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, - MeshLevel & mesh, - arrayView1d< string const > const & ) - { - // map: regionName -> subRegionName -> setName -> numComps to check pressure/comp are present consistent - map< string, map< string, map< string, ComponentMask< MAX_NC > > > > bcPresCompStatusMap; - // map: regionName -> subRegionName -> setName check to that temperature is present/consistent - map< string, map< string, set< string > > > bcTempStatusMap; - - // 1. Check pressure Dirichlet BCs - fsManager.apply< ElementSubRegionBase >( time, - mesh, - fields::flow::pressure::key(), - [&]( FieldSpecificationBase const &, - string const & setName, - SortedArrayView< localIndex const > const &, - ElementSubRegionBase & subRegion, - string const & ) - { - // Check whether pressure has already been applied to this set - string const & subRegionName = subRegion.getName(); - string const & regionName = subRegion.getParent().getParent().getName(); - - auto & subRegionSetMap = bcPresCompStatusMap[regionName][subRegionName]; - if( subRegionSetMap.count( setName ) > 0 ) - { - bcConsistent = false; - GEOS_WARNING( GEOS_FMT( "Conflicting pressure boundary conditions on set {}/{}/{}", regionName, subRegionName, setName ) ); - } - subRegionSetMap[setName].setNumComp( m_numComponents ); - } ); - } ); - return bcConsistent; -} - -void ImmiscibleMultiphaseFlow::applyDirichletBC( real64 const time_n, - real64 const dt, - DofManager const & dofManager, - DomainPartition & domain, - CRSMatrixView< real64, globalIndex const > const & localMatrix, - arrayView1d< real64 > const & localRhs ) const -{ - GEOS_MARK_FUNCTION; - - // Only validate BC at the beginning of Newton loop - if( m_nonlinearSolverParameters.m_numNewtonIterations == 0 ) - { - bool const bcConsistent = validateDirichletBC( domain, time_n + dt ); - GEOS_ERROR_IF( !bcConsistent, GEOS_FMT( "ImmiscibleMultiphaseFlow {}: inconsistent boundary conditions", getDataContext() ) ); - } - - FieldSpecificationManager & fsManager = FieldSpecificationManager::getInstance(); - - forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, - MeshLevel & mesh, - arrayView1d< string const > const & ) - { - - // 1. Apply pressure Dirichlet BCs, store in a separate field - applyFieldValue< ElementSubRegionBase >( time_n, dt, mesh, bcLogMessage, - fields::flow::pressure::key(), fields::flow::bcPressure::key() ); - // 2. Apply composition BC (global component fraction) and store them for constitutive call - applyFieldValue< ElementSubRegionBase >( time_n, dt, mesh, bcLogMessage, - fields::flow::globalCompFraction::key(), fields::flow::globalCompFraction::key() ); - // 3. Apply temperature Dirichlet BCs, store in a separate field - if( m_isThermal ) - { - applyFieldValue< ElementSubRegionBase >( time_n, dt, mesh, bcLogMessage, - fields::flow::temperature::key(), fields::flow::bcTemperature::key() ); - } - - globalIndex const rankOffset = dofManager.rankOffset(); - string const dofKey = dofManager.getKey( viewKeyStruct::elemDofFieldString() ); - - // 4. Call constitutive update, back-calculate target global component densities and apply to the system - fsManager.apply< ElementSubRegionBase >( time_n + dt, - mesh, - fields::flow::pressure::key(), - [&] ( FieldSpecificationBase const &, - string const &, - SortedArrayView< localIndex const > const & targetSet, - ElementSubRegionBase & subRegion, - string const & ) - { - string const & fluidName = subRegion.getReference< string >( viewKeyStruct::fluidNamesString() ); - MultiFluidBase & fluid = getConstitutiveModel< MultiFluidBase >( subRegion, fluidName ); - - // in the isothermal case, we use the reservoir temperature to enforce the boundary condition - // in the thermal case, the validation function guarantees that temperature has been provided - string const temperatureKey = m_isThermal ? fields::flow::bcTemperature::key() : fields::flow::temperature::key(); - - arrayView1d< real64 const > const bcPres = - subRegion.getReference< array1d< real64 > >( fields::flow::bcPressure::key() ); - arrayView1d< real64 const > const bcTemp = - subRegion.getReference< array1d< real64 > >( temperatureKey ); - arrayView2d< real64 const, compflow::USD_COMP > const compFrac = - subRegion.getReference< array2d< real64, compflow::LAYOUT_COMP > >( fields::flow::globalCompFraction::key() ); - - constitutiveUpdatePassThru( fluid, [&] ( auto & castedFluid ) - { - using FluidType = TYPEOFREF( castedFluid ); - using ExecPolicy = typename FluidType::exec_policy; - typename FluidType::KernelWrapper fluidWrapper = castedFluid.createKernelWrapper(); - - thermalImmiscibleMultiphaseFlowKernels:: - FluidUpdateKernel:: - launch< ExecPolicy >( targetSet, - fluidWrapper, - bcPres, - bcTemp, - compFrac ); - } ); - - arrayView1d< integer const > const ghostRank = - subRegion.getReference< array1d< integer > >( ObjectManagerBase::viewKeyStruct::ghostRankString() ); - arrayView1d< globalIndex const > const dofNumber = - subRegion.getReference< array1d< globalIndex > >( dofKey ); - arrayView1d< real64 const > const pres = - subRegion.getReference< array1d< real64 > >( fields::flow::pressure::key() ); - arrayView2d< real64 const, compflow::USD_COMP > const compDens = - subRegion.getReference< array2d< real64, compflow::LAYOUT_COMP > >( fields::flow::globalCompDensity::key() ); - arrayView2d< real64 const, multifluid::USD_FLUID > const totalDens = fluid.totalDensity(); - - integer const numComp = m_numComponents; - forAll< parallelDevicePolicy<> >( targetSet.size(), [=] GEOS_HOST_DEVICE ( localIndex const a ) - { - localIndex const ei = targetSet[a]; - if( ghostRank[ei] >= 0 ) - { - return; - } - - globalIndex const dofIndex = dofNumber[ei]; - localIndex const localRow = dofIndex - rankOffset; - real64 rhsValue; - - // 4.1. Apply pressure value to the matrix/rhs - FieldSpecificationEqual::SpecifyFieldValue( dofIndex, - rankOffset, - localMatrix, - rhsValue, - bcPres[ei], - pres[ei] ); - localRhs[localRow] = rhsValue; - - // 4.2. For each component, apply target global density value - for( integer ic = 0; ic < numComp; ++ic ) - { - FieldSpecificationEqual::SpecifyFieldValue( dofIndex + ic + 1, - rankOffset, - localMatrix, - rhsValue, - totalDens[ei][0] * compFrac[ei][ic], - compDens[ei][ic] ); - localRhs[localRow + ic + 1] = rhsValue; - } - } ); - } ); - - // 5. Apply temperature to the system - if( m_isThermal ) - { - fsManager.apply< ElementSubRegionBase >( time_n + dt, - mesh, - fields::flow::temperature::key(), - [&] ( FieldSpecificationBase const &, - string const &, - SortedArrayView< localIndex const > const & targetSet, - ElementSubRegionBase & subRegion, - string const & ) - { - arrayView1d< integer const > const ghostRank = - subRegion.getReference< array1d< integer > >( ObjectManagerBase::viewKeyStruct::ghostRankString() ); - arrayView1d< globalIndex const > const dofNumber = - subRegion.getReference< array1d< globalIndex > >( dofKey ); - arrayView1d< real64 const > const bcTemp = - subRegion.getReference< array1d< real64 > >( fields::flow::bcTemperature::key() ); - arrayView1d< real64 const > const temp = - subRegion.getReference< array1d< real64 > >( fields::flow::temperature::key() ); - - integer const numComp = m_numComponents; - forAll< parallelDevicePolicy<> >( targetSet.size(), [=] GEOS_HOST_DEVICE ( localIndex const a ) - { - localIndex const ei = targetSet[a]; - if( ghostRank[ei] >= 0 ) - { - return; - } - - globalIndex const dofIndex = dofNumber[ei]; - localIndex const localRow = dofIndex - rankOffset; - real64 rhsValue; - - // 4.2. Apply temperature value to the matrix/rhs - FieldSpecificationEqual::SpecifyFieldValue( dofIndex + numComp + 1, - rankOffset, - localMatrix, - rhsValue, - bcTemp[ei], - temp[ei] ); - localRhs[localRow + numComp + 1] = rhsValue; - } ); - } ); - } - } ); -} - - void ImmiscibleMultiphaseFlow::resetStateToBeginningOfStep( DomainPartition & domain ) { @@ -1048,11 +782,6 @@ void ImmiscibleMultiphaseFlow::implicitStepComplete( real64 const & time, isothermalImmiscibleMultiphaseFlowKernels::StatisticsKernel:: saveDeltaPressure< parallelDevicePolicy<> >( subRegion.size(), pres, initPres, deltaPres ); - // Step 2: save the converged fluid state - string const & fluidName = subRegion.getReference< string >( viewKeyStruct::fluidNamesString() ); - MultiFluidBase const & fluidMaterial = getConstitutiveModel< MultiFluidBase >( subRegion, fluidName ); - fluidMaterial.saveConvergedState(); - // Step 3: save the converged solid state string const & solidName = subRegion.getReference< string >( viewKeyStruct::solidNamesString() ); CoupledSolidBase const & porousMaterial = getConstitutiveModel< CoupledSolidBase >( subRegion, solidName ); @@ -1097,24 +826,12 @@ void ImmiscibleMultiphaseFlow::saveConvergedState( ElementSubRegionBase & subReg { FlowSolverBase::saveConvergedState( subRegion ); - arrayView2d< real64 const, compflow::USD_COMP > const & compDens = - subRegion.template getField< fields::flow::globalCompDensity >(); - arrayView2d< real64, compflow::USD_COMP > const & compDens_n = - subRegion.template getField< fields::flow::globalCompDensity_n >(); - compDens_n.setValues< parallelDevicePolicy<> >( compDens ); - - arrayView2d< real64 const, compflow::USD_COMP > const & compAmount = - subRegion.template getField< fields::flow::compAmount >(); - arrayView2d< real64, compflow::USD_COMP > const & compAmount_n = - subRegion.template getField< fields::flow::compAmount_n >(); - compAmount_n.setValues< parallelDevicePolicy<> >( compAmount ); + arrayView2d< real64 const, compflow::USD_PHASE > const phaseVolFrac = + subRegion.getField< fields::flow::phaseVolumeFraction >(); + arrayView2d< real64, compflow::USD_PHASE > const phaseVolFrac_n = + subRegion.getField< fields::flow::phaseVolumeFraction_n >(); + phaseVolFrac_n.setValues< parallelDevicePolicy<> >( phaseVolFrac ); - if( m_isFixedStressPoromechanicsUpdate ) - { - arrayView2d< real64, compflow::USD_COMP > const & compDens_k = - subRegion.template getField< fields::flow::globalCompDensity_k >(); - compDens_k.setValues< parallelDevicePolicy<> >( compDens ); - } } void ImmiscibleMultiphaseFlow::updateState( DomainPartition & domain ) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp index ec5c2605c20..1480c0fc0d9 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp @@ -73,14 +73,7 @@ class ImmiscibleMultiphaseFlow : public FlowSolverBase */ string getCatalogName() const override { return catalogName(); } - virtual void registerDataOnMesh( Group & meshBodies ) override; - - /** - * @defgroup Solver Interface Functions - * - * These functions provide the primary interface that is required for derived classes - */ - /**@{*/ + virtual void registerDataOnMesh( Group & meshBodies ) override final; virtual void implicitStepSetup( real64 const & time_n, @@ -134,16 +127,14 @@ class ImmiscibleMultiphaseFlow : public FlowSolverBase * @brief Recompute phase mobility from constitutive and primary variables * @param dataGroup the group storing the required field */ - virtual void updatePhaseMobility( ObjectManagerBase & dataGroup ) const = 0; + void updatePhaseMobility( ObjectManagerBase & dataGroup ) const; real64 updateFluidState( ElementSubRegionBase & subRegion ) const; virtual void saveConvergedState( ElementSubRegionBase & subRegion ) const override final; - virtual void updateState( DomainPartition & domain ) override final; - /** * @brief Getter for the number of fluid phases * @return the number of phases diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlowFields.hpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlowFields.hpp new file mode 100644 index 00000000000..2c2db7636d8 --- /dev/null +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlowFields.hpp @@ -0,0 +1,93 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * SPDX-License-Identifier: LGPL-2.1-only + * + * Copyright (c) 2016-2024 Lawrence Livermore National Security LLC + * Copyright (c) 2018-2024 Total, S.A + * Copyright (c) 2018-2024 The Board of Trustees of the Leland Stanford Junior University + * Copyright (c) 2018-2024 Chevron + * Copyright (c) 2019- GEOS/GEOSX Contributors + * All rights reserved + * + * See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details. + * ------------------------------------------------------------------------------------------------------------ + */ + +/** + * @file CompositionalMultiphaseBaseFields.hpp + */ + +#ifndef GEOS_PHYSICSSOLVERS_FLUIDFLOW_COMPOSITIONALMULTIPHASEBASEFIELDS_HPP_ +#define GEOS_PHYSICSSOLVERS_FLUIDFLOW_COMPOSITIONALMULTIPHASEBASEFIELDS_HPP_ + +#include "common/DataLayouts.hpp" +#include "mesh/MeshFields.hpp" + +namespace geos +{ +/** + * A scope for field traits. + */ +namespace fields +{ + +namespace immiscibleMultiphaseFlow +{ + +using array2dLayoutPhase = array2d< real64, immiscibleFlow::LAYOUT_PHASE >; +using array3dLayoutPhase_dS = array3d< real64, immiscibleFlow::LAYOUT_PHASE_DS >; + +DECLARE_FIELD( phaseVolumeFraction, + "phaseVolumeFraction", + array2dLayoutPhase, + 0, + LEVEL_0, + WRITE_AND_READ, + "Phase volume fraction" ); + +DECLARE_FIELD( phaseVolumeFraction_n, + "phaseVolumeFraction_n", + array2dLayoutPhase, + 0, + NOPLOT, + WRITE_AND_READ, + "Phase volume fraction at the previous converged time step" ); + +DECLARE_FIELD( phaseMobility, + "phaseMobility", + array2dLayoutPhase, + 0, + LEVEL_0, + WRITE_AND_READ, + "Phase mobility" ); + +DECLARE_FIELD( dPhaseMobility, + "dPhaseMobility", + array3dLayoutPhase_dS, + 0, + NOPLOT, + NO_WRITE, + "Derivative of phase volume fraction with respect to pressure, temperature, global component density" ); + +DECLARE_FIELD( phaseOutflux, + "phaseOutflux", + array2dLayoutPhase, + 0, + NOPLOT, + NO_WRITE, + "Phase outflux" ); + +DECLARE_FIELD( phaseCFLNumber, + "phaseCFLNumber", + array1d< real64 >, + 0, + LEVEL_0, + NO_WRITE, + "Phase CFL number" ); +} + +} + +} + +#endif // GEOS_PHYSICSSOLVERS_FLUIDFLOW_COMPOSITIONALMULTIPHASEBASEFIELDS_HPP_ From c90724affc8f514aaa8ca14e79f7a930068b572c Mon Sep 17 00:00:00 2001 From: Matteo Cusini Date: Mon, 29 Jul 2024 16:04:35 -0700 Subject: [PATCH 004/102] removed all compositional references. --- .../fluidFlow/ImmiscibleMultiphaseFlow.cpp | 111 ++++++++++-------- .../fluidFlow/ImmiscibleMultiphaseFlow.hpp | 2 +- .../ImmiscibleMultiphaseFlowFields.hpp | 16 +++ 3 files changed, 80 insertions(+), 49 deletions(-) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp index 0c7932f7ba2..dcd8af9c24c 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp @@ -123,14 +123,14 @@ void ImmiscibleMultiphaseFlow::registerDataOnMesh( Group & meshBodies ) reference().resizeDimension< 1 >( m_numPhases ); subRegion.registerField< dPhaseMobility >( getName() ). - reference().resizeDimension< 1, 2 >( m_numPhases, m_numPhases ); // dP, dT, dC + reference().resizeDimension< 1, 2 >( m_numPhases, m_numPhases ); // dP, dS } ); - FaceManager & faceManager = mesh.getFaceManager(); - { - faceManager.registerField< totalMassFlux >( getName() ); - } + // FaceManager & faceManager = mesh.getFaceManager(); + // { + // faceManager.registerField< totalMassFlux >( getName() ); + // } } ); } @@ -203,30 +203,31 @@ void ImmiscibleMultiphaseFlow::updateFluidModel( ObjectManagerBase & dataGroup ) { GEOS_MARK_FUNCTION; - arrayView1d< real64 const > const pres = dataGroup.getField< fields::flow::pressure >(); - arrayView1d< real64 const > const temp = dataGroup.getField< fields::flow::temperature >(); + // arrayView1d< real64 const > const pres = dataGroup.getField< fields::flow::pressure >(); + // arrayView1d< real64 const > const temp = dataGroup.getField< fields::flow::temperature >(); + GEOS_UNUSED_VAR(dataGroup); } void ImmiscibleMultiphaseFlow::updateRelPermModel( ObjectManagerBase & dataGroup ) const { GEOS_MARK_FUNCTION; - arrayView2d< real64 const, compflow::USD_PHASE > const phaseVolFrac = - dataGroup.getField< fields::flow::phaseVolumeFraction >(); + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFrac = + dataGroup.getField< fields::flow::immiscibleFlow::phaseVolumeFraction >(); string const & relPermName = dataGroup.getReference< string >( viewKeyStruct::relPermNamesString() ); RelativePermeabilityBase & relPerm = getConstitutiveModel< RelativePermeabilityBase >( dataGroup, relPermName ); - // constitutive::constitutiveUpdatePassThru( relPerm, [&] ( auto & castedRelPerm ) - // { - // typename TYPEOFREF( castedRelPerm ) ::KernelWrapper relPermWrapper = castedRelPerm.createKernelWrapper(); + constitutive::constitutiveUpdatePassThru( relPerm, [&] ( auto & castedRelPerm ) + { + typename TYPEOFREF( castedRelPerm ) ::KernelWrapper relPermWrapper = castedRelPerm.createKernelWrapper(); - // isothermalImmiscibleMultiphaseFlowKernels:: - // RelativePermeabilityUpdateKernel:: - // launch< parallelDevicePolicy<> >( dataGroup.size(), - // relPermWrapper, - // phaseVolFrac ); - // } ); + // isothermalImmiscibleMultiphaseFlowKernels:: + // RelativePermeabilityUpdateKernel:: + // launch< parallelDevicePolicy<> >( dataGroup.size(), + // relPermWrapper, + // phaseVolFrac ); + } ); } void ImmiscibleMultiphaseFlow::updateCapPressureModel( ObjectManagerBase & dataGroup ) const @@ -235,8 +236,8 @@ void ImmiscibleMultiphaseFlow::updateCapPressureModel( ObjectManagerBase & dataG if( m_hasCapPressure ) { - arrayView2d< real64 const, compflow::USD_PHASE > const phaseVolFrac = - dataGroup.getField< fields::flow::phaseVolumeFraction >(); + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFrac = + dataGroup.getField< fields::flow::immiscibleFlow::phaseVolumeFraction >(); string const & cappresName = dataGroup.getReference< string >( viewKeyStruct::capPressureNamesString() ); CapillaryPressureBase & capPressure = getConstitutiveModel< CapillaryPressureBase >( dataGroup, cappresName ); @@ -282,9 +283,6 @@ void ImmiscibleMultiphaseFlow::initializeFluidState( MeshLevel & mesh, } ); - // with initial component densities defined - check if they need to be corrected to avoid zero diags etc - chopNegativeDensities( domain ); - // for some reason CUDA does not want the host_device lambda to be defined inside the generic lambda // I need the exact type of the subRegion for updateSolidflowProperties to work well. mesh.getElemManager().forElementSubRegions< CellElementSubRegion, @@ -330,8 +328,8 @@ void ImmiscibleMultiphaseFlow::initializeFluidState( MeshLevel & mesh, // - This step depends on phaseVolFraction // initialized phase volume fraction - arrayView2d< real64 const, compflow::USD_PHASE > const phaseVolFrac = - subRegion.template getField< fields::flow::phaseVolumeFraction >(); + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFrac = + subRegion.template getField< fields::flow::immiscibleFlow::phaseVolumeFraction >(); string const & relpermName = subRegion.template getReference< string >( viewKeyStruct::relPermNamesString() ); RelativePermeabilityBase & relPermMaterial = @@ -460,13 +458,20 @@ ImmiscibleMultiphaseFlow::implicitStepSetup( real64 const & GEOS_UNUSED_PARAM( t updateFluidState( subRegion ); // after the update, save the new saturation - arrayView2d< real64 const, compflow::USD_PHASE > const phaseVolFrac = - subRegion.template getField< fields::flow::phaseVolumeFraction >(); + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFrac = + subRegion.template getField< fields::flow::immiscibleFlow::phaseVolumeFraction >(); - arrayView2d< real64, compflow::USD_PHASE > const phaseVolFrac_n = - subRegion.template getField< fields::flow::phaseVolumeFraction_n >(); + arrayView2d< real64, immiscibleFlow::USD_PHASE > const phaseVolFrac_n = + subRegion.template getField< fields::flow::immiscibleFlow::phaseVolumeFraction_n >(); phaseVolFrac_n.setValues< parallelDevicePolicy<> >( phaseVolFrac ); + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const & phaseMass = + subRegion.template getField< fields::flow::immiscibleFlow::phaseMass >(); + + arrayView2d< real64, immiscibleFlow::USD_PHASE > const & phaseMass_n = + subRegion.template getField< fields::flow::immiscibleFlow::phaseMass_n >(); + phaseMass_n.setValues< parallelDevicePolicy<> >( phaseMass ); + } ); } ); } @@ -481,16 +486,16 @@ void ImmiscibleMultiphaseFlow::assembleSystem( real64 const GEOS_UNUSED_PARAM( t GEOS_MARK_FUNCTION; assembleAccumulationTerm( domain, - dofManager, - localMatrix, - localRhs ); + dofManager, + localMatrix, + localRhs ); assembleFluxTerms( dt, - domain, - dofManager, - localMatrix, - localRhs ); + domain, + dofManager, + localMatrix, + localRhs ); } void ImmiscibleMultiphaseFlow::assembleAccumulationTerm( DomainPartition & domain, @@ -509,7 +514,6 @@ void ImmiscibleMultiphaseFlow::assembleAccumulationTerm( DomainPartition & domai ElementSubRegionBase const & subRegion ) { string const dofKey = dofManager.getKey( viewKeyStruct::elemDofFieldString() ); - string const & fluidName = subRegion.getReference< string >( viewKeyStruct::fluidNamesString() ); string const & solidName = subRegion.getReference< string >( viewKeyStruct::solidNamesString() ); } ); } ); @@ -735,11 +739,20 @@ void ImmiscibleMultiphaseFlow::resetStateToBeginningOfStep( DomainPartition & do subRegion.template getField< fields::flow::pressure_n >(); pres.setValues< parallelDevicePolicy<> >( pres_n ); - arrayView2d< real64, compflow::USD_COMP > const & compDens = - subRegion.template getField< fields::flow::globalCompDensity >(); - arrayView2d< real64 const, compflow::USD_COMP > const & compDens_n = - subRegion.template getField< fields::flow::globalCompDensity_n >(); - compDens.setValues< parallelDevicePolicy<> >( compDens_n ); + // after the update, save the new saturation + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFrac_n = + subRegion.template getField< fields::flow::immiscibleFlow::phaseVolumeFraction_n >(); + + arrayView2d< real64, immiscibleFlow::USD_PHASE > const phaseVolFrac = + subRegion.template getField< fields::flow::immiscibleFlow::phaseVolumeFraction >(); + phaseVolFrac.setValues< parallelDevicePolicy<> >( phaseVolFrac ); + + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const & phaseMass_n = + subRegion.template getField< fields::flow::immiscibleFlow::phaseMass_n >(); + + arrayView2d< real64, immiscibleFlow::USD_PHASE > const & phaseMass = + subRegion.template getField< fields::flow::immiscibleFlow::phaseMass >(); + phaseMass.setValues< parallelDevicePolicy<> >( phaseMass_n ); if( m_isThermal ) { @@ -795,8 +808,8 @@ void ImmiscibleMultiphaseFlow::implicitStepComplete( real64 const & time, } // Step 4: save converged state for the relperm model to handle hysteresis - arrayView2d< real64 const, compflow::USD_PHASE > const phaseVolFrac = - subRegion.getField< fields::flow::phaseVolumeFraction >(); + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFrac = + subRegion.getField< fields::flow::immiscibleFlow::phaseVolumeFraction >(); string const & relPermName = subRegion.getReference< string >( viewKeyStruct::relPermNamesString() ); RelativePermeabilityBase const & relPermMaterial = getConstitutiveModel< RelativePermeabilityBase >( subRegion, relPermName ); @@ -826,12 +839,14 @@ void ImmiscibleMultiphaseFlow::saveConvergedState( ElementSubRegionBase & subReg { FlowSolverBase::saveConvergedState( subRegion ); - arrayView2d< real64 const, compflow::USD_PHASE > const phaseVolFrac = - subRegion.getField< fields::flow::phaseVolumeFraction >(); - arrayView2d< real64, compflow::USD_PHASE > const phaseVolFrac_n = - subRegion.getField< fields::flow::phaseVolumeFraction_n >(); + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFrac = + subRegion.getField< fields::flow::immiscibleFlow::phaseVolumeFraction >(); + arrayView2d< real64, immiscibleFlow::USD_PHASE > const phaseVolFrac_n = + subRegion.getField< fields::flow::immiscibleFlow::phaseVolumeFraction_n >(); phaseVolFrac_n.setValues< parallelDevicePolicy<> >( phaseVolFrac ); + + } void ImmiscibleMultiphaseFlow::updateState( DomainPartition & domain ) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp index 1480c0fc0d9..c49cd9b8ba8 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp @@ -105,7 +105,7 @@ class ImmiscibleMultiphaseFlow : public FlowSolverBase DomainPartition & domain ) override; /** - * @brief Update all relevant fluid models using current values of pressure and composition + * @brief Update all relevant fluid models using current values of pressure and phase volume fraction * @param dataGroup the group storing the required fields */ void updateFluidModel( ObjectManagerBase & dataGroup ) const; diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlowFields.hpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlowFields.hpp index 2c2db7636d8..abf3588f0eb 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlowFields.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlowFields.hpp @@ -53,6 +53,22 @@ DECLARE_FIELD( phaseVolumeFraction_n, WRITE_AND_READ, "Phase volume fraction at the previous converged time step" ); +DECLARE_FIELD( phaseMass, + "phaseMass", + array2dLayoutPhase, + 0, + LEVEL_0, + WRITE_AND_READ, + "Phase mass" ); + +DECLARE_FIELD( phaseMass_n, + "phaseMass_n", + array2dLayoutPhase, + 0, + NOPLOT, + WRITE_AND_READ, + "Phase mass at the previous converged time step" ); + DECLARE_FIELD( phaseMobility, "phaseMobility", array2dLayoutPhase, From 446e4010fdc57f2a7aa245fcbd70a807f0771830 Mon Sep 17 00:00:00 2001 From: Matteo Cusini Date: Tue, 30 Jul 2024 11:36:46 -0700 Subject: [PATCH 005/102] Compiles and links. --- .../physicsSolvers/fluidFlow/CMakeLists.txt | 1 + .../fluidFlow/ImmiscibleMultiphaseFlow.cpp | 421 +++++------------- .../fluidFlow/ImmiscibleMultiphaseFlow.hpp | 97 ++-- .../ImmiscibleMultiphaseFlowFields.hpp | 8 +- ...rmalCompositionalMultiphaseBaseKernels.hpp | 1 + 5 files changed, 169 insertions(+), 359 deletions(-) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/CMakeLists.txt b/src/coreComponents/physicsSolvers/fluidFlow/CMakeLists.txt index 65e1180ffe2..e2e7320694d 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/CMakeLists.txt +++ b/src/coreComponents/physicsSolvers/fluidFlow/CMakeLists.txt @@ -8,6 +8,7 @@ set( physicsSolvers_headers fluidFlow/ThermalCompositionalMultiphaseBaseKernels.hpp fluidFlow/CompositionalMultiphaseFVM.hpp fluidFlow/ImmiscibleMultiphaseFlow.hpp + fluidFlow/ImmiscibleMultiphaseFlowFields.hpp fluidFlow/IsothermalCompositionalMultiphaseFVMKernels.hpp fluidFlow/IsothermalCompositionalMultiphaseFVMKernelUtilities.hpp fluidFlow/ThermalCompositionalMultiphaseFVMKernels.hpp diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp index dcd8af9c24c..9a93fec7e66 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp @@ -19,11 +19,19 @@ #include "ImmiscibleMultiphaseFlow.hpp" +#include "FlowSolverBaseFields.hpp" +#include "physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlowFields.hpp" +#include "physicsSolvers/fluidFlow/IsothermalCompositionalMultiphaseBaseKernels.hpp" +#include "physicsSolvers/fluidFlow/IsothermalCompositionalMultiphaseFVMKernels.hpp" -#include "ImmiscibleMultiphaseFlowFields.hpp" #include "constitutive/ConstitutiveManager.hpp" #include "constitutive/capillaryPressure/CapillaryPressureFields.hpp" #include "constitutive/capillaryPressure/capillaryPressureSelector.hpp" +#include "constitutive/relativePermeability/RelativePermeabilitySelector.hpp" + +#include "fieldSpecification/SourceFluxBoundaryCondition.hpp" + + #include "constitutive/ConstitutivePassThru.hpp" #if defined( __INTEL_COMPILER ) @@ -35,10 +43,10 @@ namespace geos using namespace dataRepository; using namespace constitutive; -using namespace fields:flow:immiscibleFlow; +using namespace fields::immiscibleMultiphaseFlow; ImmiscibleMultiphaseFlow::ImmiscibleMultiphaseFlow( const string & name, - Group * const parent ) + Group * const parent ) : FlowSolverBase( name, parent ), m_numPhases( 2 ), @@ -56,12 +64,10 @@ void ImmiscibleMultiphaseFlow::postInputInitialization() void ImmiscibleMultiphaseFlow::registerDataOnMesh( Group & meshBodies ) { - using namespace fields::flow; - FlowSolverBase::registerDataOnMesh( meshBodies ); - DomainPartition const & domain = this->getGroupByPath< DomainPartition >( "/Problem/domain" ); - ConstitutiveManager const & cm = domain.getConstitutiveManager(); + // DomainPartition const & domain = this->getGroupByPath< DomainPartition >( "/Problem/domain" ); + // ConstitutiveManager const & cm = domain.getConstitutiveManager(); // 0. Find a "reference" fluid model name (at this point, models are already attached to subregions) forDiscretizationOnMeshTargets( meshBodies, [&]( string const &, @@ -112,14 +118,12 @@ void ImmiscibleMultiphaseFlow::registerDataOnMesh( Group & meshBodies ) // The resizing of the arrays needs to happen here, before the call to initializePreSubGroups, // to make sure that the dimensions are properly set before the timeHistoryOutput starts its initialization. subRegion.registerField< phaseVolumeFraction >( getName() ). - setDimLabels( 1, fluid.phaseNames() ). reference().resizeDimension< 1 >( m_numPhases ); - + subRegion.registerField< phaseVolumeFraction_n >( getName() ). - reference().resizeDimension< 1 >( m_numPhases ); + reference().resizeDimension< 1 >( m_numPhases ); subRegion.registerField< phaseMobility >( getName() ). - setDimLabels( 1, fluid.phaseNames() ). reference().resizeDimension< 1 >( m_numPhases ); subRegion.registerField< dPhaseMobility >( getName() ). @@ -156,10 +160,10 @@ void ImmiscibleMultiphaseFlow::initializePreSubGroups() FlowSolverBase::initializePreSubGroups(); DomainPartition & domain = this->getGroupByPath< DomainPartition >( "/Problem/domain" ); - ConstitutiveManager const & cm = domain.getConstitutiveManager(); + // ConstitutiveManager const & cm = domain.getConstitutiveManager(); - // 1. Validate various models against each other (must have same phases and components) - validateConstitutiveModels( domain ); + // // 1. Validate various models against each other (must have same phases and components) + // validateConstitutiveModels( domain ); // 2. Set the value of temperature forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, @@ -177,43 +181,23 @@ void ImmiscibleMultiphaseFlow::initializePreSubGroups() } ); } -void ImmiscibleMultiphaseFlow::validateConstitutiveModels( DomainPartition const & domain ) const -{ - GEOS_MARK_FUNCTION; - - ConstitutiveManager const & cm = domain.getConstitutiveManager(); - - forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, - MeshLevel const & mesh, - arrayView1d< string const > const & regionNames ) - - { - mesh.getElemManager().forElementSubRegions( regionNames, - [&]( localIndex const, - ElementSubRegionBase const & subRegion ) - { - string const & relpermName = subRegion.getReference< string >( viewKeyStruct::relPermNamesString() ); - RelativePermeabilityBase const & relPerm = getConstitutiveModel< RelativePermeabilityBase >( subRegion, relpermName ); - compareMultiphaseModels( relPerm, referenceFluid ); - } ); - } ); -} - void ImmiscibleMultiphaseFlow::updateFluidModel( ObjectManagerBase & dataGroup ) const { GEOS_MARK_FUNCTION; // arrayView1d< real64 const > const pres = dataGroup.getField< fields::flow::pressure >(); // arrayView1d< real64 const > const temp = dataGroup.getField< fields::flow::temperature >(); - GEOS_UNUSED_VAR(dataGroup); + GEOS_UNUSED_VAR( dataGroup ); } void ImmiscibleMultiphaseFlow::updateRelPermModel( ObjectManagerBase & dataGroup ) const { GEOS_MARK_FUNCTION; + GEOS_UNUSED_VAR( dataGroup ); + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFrac = - dataGroup.getField< fields::flow::immiscibleFlow::phaseVolumeFraction >(); + dataGroup.getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); string const & relPermName = dataGroup.getReference< string >( viewKeyStruct::relPermNamesString() ); RelativePermeabilityBase & relPerm = getConstitutiveModel< RelativePermeabilityBase >( dataGroup, relPermName ); @@ -222,11 +206,11 @@ void ImmiscibleMultiphaseFlow::updateRelPermModel( ObjectManagerBase & dataGroup { typename TYPEOFREF( castedRelPerm ) ::KernelWrapper relPermWrapper = castedRelPerm.createKernelWrapper(); - // isothermalImmiscibleMultiphaseFlowKernels:: - // RelativePermeabilityUpdateKernel:: - // launch< parallelDevicePolicy<> >( dataGroup.size(), - // relPermWrapper, - // phaseVolFrac ); + isothermalCompositionalMultiphaseBaseKernels:: + RelativePermeabilityUpdateKernel:: + launch< parallelDevicePolicy<> >( dataGroup.size(), + relPermWrapper, + phaseVolFrac ); } ); } @@ -237,7 +221,7 @@ void ImmiscibleMultiphaseFlow::updateCapPressureModel( ObjectManagerBase & dataG if( m_hasCapPressure ) { arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFrac = - dataGroup.getField< fields::flow::immiscibleFlow::phaseVolumeFraction >(); + dataGroup.getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); string const & cappresName = dataGroup.getReference< string >( viewKeyStruct::capPressureNamesString() ); CapillaryPressureBase & capPressure = getConstitutiveModel< CapillaryPressureBase >( dataGroup, cappresName ); @@ -246,7 +230,7 @@ void ImmiscibleMultiphaseFlow::updateCapPressureModel( ObjectManagerBase & dataG { typename TYPEOFREF( castedCapPres ) ::KernelWrapper capPresWrapper = castedCapPres.createKernelWrapper(); - isothermalImmiscibleMultiphaseFlowKernels:: + isothermalCompositionalMultiphaseBaseKernels:: CapillaryPressureUpdateKernel:: launch< parallelDevicePolicy<> >( dataGroup.size(), capPresWrapper, @@ -255,7 +239,7 @@ void ImmiscibleMultiphaseFlow::updateCapPressureModel( ObjectManagerBase & dataG } } -real64 ImmiscibleMultiphaseFlow::updateFluidState( ElementSubRegionBase & subRegion ) const +void ImmiscibleMultiphaseFlow::updateFluidState( ElementSubRegionBase & subRegion ) const { GEOS_MARK_FUNCTION; @@ -263,13 +247,34 @@ real64 ImmiscibleMultiphaseFlow::updateFluidState( ElementSubRegionBase & subReg updateRelPermModel( subRegion ); updatePhaseMobility( subRegion ); updateCapPressureModel( subRegion ); +} - return maxDeltaPhaseVolFrac; +void ImmiscibleMultiphaseFlow::updatePhaseMobility( ObjectManagerBase & dataGroup ) const +{ + GEOS_MARK_FUNCTION; + + GEOS_UNUSED_VAR( dataGroup ); + + /// Matteo: looks like you will to create a new update function for the mobility. I have left the code as an example. + // // note that the phase mobility computed here also includes phase density + // string const & fluidName = dataGroup.getReference< string >( viewKeyStruct::fluidNamesString() ); + // MultiFluidBase const & fluid = getConstitutiveModel< MultiFluidBase >( dataGroup, fluidName ); + + // string const & relpermName = dataGroup.getReference< string >( viewKeyStruct::relPermNamesString() ); + // RelativePermeabilityBase const & relperm = getConstitutiveModel< RelativePermeabilityBase >( dataGroup, relpermName ); + + // isothermalCompositionalMultiphaseFVMKernels:: + // PhaseMobilityKernelFactory:: + // createAndLaunch< parallelDevicePolicy<> >( m_numComponents, + // m_numPhases, + // dataGroup, + // fluid, + // relperm ); } void ImmiscibleMultiphaseFlow::initializeFluidState( MeshLevel & mesh, - DomainPartition & domain, - arrayView1d< string const > const & regionNames ) + DomainPartition & GEOS_UNUSED_PARAM( domain ), + arrayView1d< string const > const & regionNames ) { GEOS_MARK_FUNCTION; @@ -305,8 +310,6 @@ void ImmiscibleMultiphaseFlow::initializeFluidState( MeshLevel & mesh, porousSolid.scaleReferencePorosity( netToGross ); saveConvergedState( subRegion ); // necessary for a meaningful porosity update in sequential schemes updatePorosityAndPermeability( subRegion ); - updateCompAmount( subRegion ); - updatePhaseVolumeFraction( subRegion ); // Now, we initialize and update each constitutive model one by one @@ -329,7 +332,7 @@ void ImmiscibleMultiphaseFlow::initializeFluidState( MeshLevel & mesh, // initialized phase volume fraction arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFrac = - subRegion.template getField< fields::flow::immiscibleFlow::phaseVolumeFraction >(); + subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); string const & relpermName = subRegion.template getReference< string >( viewKeyStruct::relPermNamesString() ); RelativePermeabilityBase & relPermMaterial = @@ -349,8 +352,7 @@ void ImmiscibleMultiphaseFlow::initializeFluidState( MeshLevel & mesh, arrayView2d< real64 const > const porosity = porousMaterial.getPorosity(); string const & permName = subRegion.template getReference< string >( viewKeyStruct::permeabilityNamesString() ); - PermeabilityBase const & permeabilityMaterial = - getConstitutiveModel< PermeabilityBase >( subRegion, permName ); + PermeabilityBase const & permeabilityMaterial = getConstitutiveModel< PermeabilityBase >( subRegion, permName ); // initialized permeability arrayView3d< real64 const > const permeability = permeabilityMaterial.permeability(); @@ -397,7 +399,7 @@ void ImmiscibleMultiphaseFlow::initializePostInitialConditionsPreSubGroups() { FieldIdentifiers fieldsToBeSync; fieldsToBeSync.addElementFields( { fields::flow::pressure::key(), - fields::flow::globalCompDensity::key() }, + fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key() }, regionNames ); CommunicationTools::getInstance().synchronizeFields( fieldsToBeSync, mesh, domain.getNeighbors(), false ); @@ -438,8 +440,8 @@ void ImmiscibleMultiphaseFlow::initializePostInitialConditionsPreSubGroups() void ImmiscibleMultiphaseFlow::implicitStepSetup( real64 const & GEOS_UNUSED_PARAM( time_n ), - real64 const & GEOS_UNUSED_PARAM( dt ), - DomainPartition & domain ) + real64 const & GEOS_UNUSED_PARAM( dt ), + DomainPartition & domain ) { forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, MeshLevel & mesh, @@ -459,17 +461,17 @@ ImmiscibleMultiphaseFlow::implicitStepSetup( real64 const & GEOS_UNUSED_PARAM( t // after the update, save the new saturation arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFrac = - subRegion.template getField< fields::flow::immiscibleFlow::phaseVolumeFraction >(); + subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); arrayView2d< real64, immiscibleFlow::USD_PHASE > const phaseVolFrac_n = - subRegion.template getField< fields::flow::immiscibleFlow::phaseVolumeFraction_n >(); + subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction_n >(); phaseVolFrac_n.setValues< parallelDevicePolicy<> >( phaseVolFrac ); arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const & phaseMass = - subRegion.template getField< fields::flow::immiscibleFlow::phaseMass >(); - + subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseMass >(); + arrayView2d< real64, immiscibleFlow::USD_PHASE > const & phaseMass_n = - subRegion.template getField< fields::flow::immiscibleFlow::phaseMass_n >(); + subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseMass_n >(); phaseMass_n.setValues< parallelDevicePolicy<> >( phaseMass ); } ); @@ -477,11 +479,11 @@ ImmiscibleMultiphaseFlow::implicitStepSetup( real64 const & GEOS_UNUSED_PARAM( t } void ImmiscibleMultiphaseFlow::assembleSystem( real64 const GEOS_UNUSED_PARAM( time_n ), - real64 const dt, - DomainPartition & domain, - DofManager const & dofManager, - CRSMatrixView< real64, globalIndex const > const & localMatrix, - arrayView1d< real64 > const & localRhs ) + real64 const dt, + DomainPartition & domain, + DofManager const & dofManager, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) { GEOS_MARK_FUNCTION; @@ -490,7 +492,7 @@ void ImmiscibleMultiphaseFlow::assembleSystem( real64 const GEOS_UNUSED_PARAM( t localMatrix, localRhs ); - + assembleFluxTerms( dt, domain, dofManager, @@ -499,227 +501,61 @@ void ImmiscibleMultiphaseFlow::assembleSystem( real64 const GEOS_UNUSED_PARAM( t } void ImmiscibleMultiphaseFlow::assembleAccumulationTerm( DomainPartition & domain, - DofManager const & dofManager, - CRSMatrixView< real64, globalIndex const > const & localMatrix, - arrayView1d< real64 > const & localRhs ) const + DofManager const & dofManager, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) const { GEOS_MARK_FUNCTION; - forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, - MeshLevel const & mesh, - arrayView1d< string const > const & regionNames ) - { - mesh.getElemManager().forElementSubRegions( regionNames, - [&]( localIndex const, - ElementSubRegionBase const & subRegion ) - { - string const dofKey = dofManager.getKey( viewKeyStruct::elemDofFieldString() ); - string const & solidName = subRegion.getReference< string >( viewKeyStruct::solidNamesString() ); - } ); - } ); + + GEOS_UNUSED_VAR( domain, dofManager, localMatrix, localRhs ); + + // forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, + // MeshLevel const & mesh, + // arrayView1d< string const > const & regionNames ) + // { + // mesh.getElemManager().forElementSubRegions( regionNames, + // [&]( localIndex const, + // ElementSubRegionBase const & subRegion ) + // { + // string const dofKey = dofManager.getKey( viewKeyStruct::elemDofFieldString() ); + // string const & solidName = subRegion.getReference< string >( viewKeyStruct::solidNamesString() ); + // } ); + // } ); } void ImmiscibleMultiphaseFlow::assembleFluxTerms( real64 const dt, - DomainPartition const & domain, - DofManager const & dofManager, - CRSMatrixView< real64, globalIndex const > const & localMatrix, - arrayView1d< real64 > const & localRhs ) const -{} + DomainPartition const & domain, + DofManager const & dofManager, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) const +{ + GEOS_UNUSED_VAR( dt, domain, dofManager, localMatrix, localRhs ); +} void ImmiscibleMultiphaseFlow::applyBoundaryConditions( real64 const time_n, - real64 const dt, - DomainPartition & domain, - DofManager const & dofManager, - CRSMatrixView< real64, globalIndex const > const & localMatrix, - arrayView1d< real64 > const & localRhs ) + real64 const dt, + DomainPartition & domain, + DofManager const & dofManager, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) { GEOS_MARK_FUNCTION; // apply pressure boundary conditions. applyDirichletBC( time_n, dt, dofManager, domain, localMatrix.toViewConstSizes(), localRhs.toView() ); - - // apply flux boundary conditions - applySourceFluxBC( time_n, dt, dofManager, domain, localMatrix.toViewConstSizes(), localRhs.toView() ); -} - -namespace -{ -char const bcLogMessage[] = - "ImmiscibleMultiphaseFlow {}: at time {}s, " - "the <{}> boundary condition '{}' is applied to the element set '{}' in subRegion '{}'. " - "\nThe scale of this boundary condition is {} and multiplies the value of the provided function (if any). " - "\nThe total number of target elements (including ghost elements) is {}. " - "\nNote that if this number is equal to zero for all subRegions, the boundary condition will not be applied on this element set."; } -void ImmiscibleMultiphaseFlow::applySourceFluxBC( real64 const time, - real64 const dt, - DofManager const & dofManager, - DomainPartition & domain, - CRSMatrixView< real64, globalIndex const > const & localMatrix, - arrayView1d< real64 > const & localRhs ) const +void ImmiscibleMultiphaseFlow::applyDirichletBC( real64 const time, + real64 const dt, + DofManager const & dofManager, + DomainPartition & domain, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) const { - GEOS_MARK_FUNCTION; - - FieldSpecificationManager & fsManager = FieldSpecificationManager::getInstance(); - - string const dofKey = dofManager.getKey( viewKeyStruct::elemDofFieldString() ); - - // Step 1: count individual source flux boundary conditions - - std::map< string, localIndex > bcNameToBcId; - localIndex bcCounter = 0; - - fsManager.forSubGroups< SourceFluxBoundaryCondition >( [&] ( SourceFluxBoundaryCondition const & bc ) - { - // collect all the bc names to idx - bcNameToBcId[bc.getName()] = bcCounter; - bcCounter++; - } ); - - if( bcCounter == 0 ) - { - return; - } - - // Step 2: count the set size for each source flux (each source flux may have multiple target sets) - - array1d< globalIndex > bcAllSetsSize( bcNameToBcId.size() ); - - computeSourceFluxSizeScalingFactor( time, - dt, - domain, - bcNameToBcId, - bcAllSetsSize.toView() ); - - // Step 3: we are ready to impose the boundary condition, normalized by the set size - - forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, - MeshLevel & mesh, - arrayView1d< string const > const & ) - { - fsManager.apply< ElementSubRegionBase, - SourceFluxBoundaryCondition >( time + dt, - mesh, - SourceFluxBoundaryCondition::catalogName(), - [&]( SourceFluxBoundaryCondition const & fs, - string const & setName, - SortedArrayView< localIndex const > const & targetSet, - ElementSubRegionBase & subRegion, - string const & ) - { - if( fs.getLogLevel() >= 1 && m_nonlinearSolverParameters.m_numNewtonIterations == 0 ) - { - globalIndex const numTargetElems = MpiWrapper::sum< globalIndex >( targetSet.size() ); - GEOS_LOG_RANK_0( GEOS_FMT( bcLogMessage, - getName(), time+dt, fs.getCatalogName(), fs.getName(), - setName, subRegion.getName(), fs.getScale(), numTargetElems ) ); - } - - if( targetSet.size() == 0 ) - { - return; - } - if( !subRegion.hasWrapper( dofKey ) ) - { - if( fs.getLogLevel() >= 1 ) - { - GEOS_LOG_RANK( GEOS_FMT( "{}: trying to apply SourceFlux, but its targetSet named '{}' intersects with non-simulated region named '{}'.", - getDataContext(), setName, subRegion.getName() ) ); - } - return; - } - - arrayView1d< globalIndex const > const dofNumber = subRegion.getReference< array1d< globalIndex > >( dofKey ); - arrayView1d< integer const > const ghostRank = subRegion.ghostRank(); - - // Step 3.1: get the values of the source boundary condition that need to be added to the rhs - // We don't use FieldSpecificationBase::applyConditionToSystem here because we want to account for the row permutation used in the - // compositional solvers - - array1d< globalIndex > dofArray( targetSet.size() ); - array1d< real64 > rhsContributionArray( targetSet.size() ); - arrayView1d< real64 > rhsContributionArrayView = rhsContributionArray.toView(); - localIndex const rankOffset = dofManager.rankOffset(); - - RAJA::ReduceSum< parallelDeviceReduce, real64 > massProd( 0.0 ); - - // note that the dofArray will not be used after this step (simpler to use dofNumber instead) - fs.computeRhsContribution< FieldSpecificationAdd, - parallelDevicePolicy<> >( targetSet.toViewConst(), - time + dt, - dt, - subRegion, - dofNumber, - rankOffset, - localMatrix, - dofArray.toView(), - rhsContributionArrayView, - [] GEOS_HOST_DEVICE ( localIndex const ) - { - return 0.0; - } ); - - // Step 3.2: we are ready to add the right-hand side contributions, taking into account our equation layout - - // get the normalizer - real64 const sizeScalingFactor = bcAllSetsSize[bcNameToBcId.at( fs.getName())]; - - integer const fluidComponentId = fs.getComponent(); - integer const numFluidComponents = m_numComponents; - integer const useTotalMassEquation = m_useTotalMassEquation; - forAll< parallelDevicePolicy<> >( targetSet.size(), [sizeScalingFactor, - targetSet, - rankOffset, - ghostRank, - fluidComponentId, - numFluidComponents, - useTotalMassEquation, - dofNumber, - rhsContributionArrayView, - localRhs, - massProd] GEOS_HOST_DEVICE ( localIndex const a ) - { - // we need to filter out ghosts here, because targetSet may contain them - localIndex const ei = targetSet[a]; - if( ghostRank[ei] >= 0 ) - { - return; - } - - real64 const rhsValue = rhsContributionArrayView[a] / sizeScalingFactor; // scale the contribution by the sizeScalingFactor here! - massProd += rhsValue; - if( useTotalMassEquation > 0 ) - { - // for all "fluid components", we add the value to the total mass balance equation - globalIndex const totalMassBalanceRow = dofNumber[ei] - rankOffset; - localRhs[totalMassBalanceRow] += rhsValue; - if( fluidComponentId < numFluidComponents - 1 ) - { - globalIndex const compMassBalanceRow = totalMassBalanceRow + fluidComponentId + 1; // component mass bal equations are shifted - localRhs[compMassBalanceRow] += rhsValue; - } - } - else - { - globalIndex const compMassBalanceRow = dofNumber[ei] - rankOffset + fluidComponentId; - localRhs[compMassBalanceRow] += rhsValue; - } - } ); - - SourceFluxStatsAggregator::forAllFluxStatWrappers( subRegion, fs.getName(), - [&]( SourceFluxStatsAggregator::WrappedStats & wrapper ) - { - // set the new sub-region statistics for this timestep - array1d< real64 > massProdArr{ m_numComponents }; - massProdArr[fluidComponentId] = massProd.get(); - wrapper.gatherTimeStepStats( time, dt, massProdArr.toViewConst(), targetSet.size() ); - } ); - } ); - } ); + GEOS_UNUSED_VAR( time, dt, dofManager, domain, localMatrix, localRhs ); } - void ImmiscibleMultiphaseFlow::resetStateToBeginningOfStep( DomainPartition & domain ) { GEOS_MARK_FUNCTION; @@ -741,17 +577,17 @@ void ImmiscibleMultiphaseFlow::resetStateToBeginningOfStep( DomainPartition & do // after the update, save the new saturation arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFrac_n = - subRegion.template getField< fields::flow::immiscibleFlow::phaseVolumeFraction_n >(); + subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction_n >(); arrayView2d< real64, immiscibleFlow::USD_PHASE > const phaseVolFrac = - subRegion.template getField< fields::flow::immiscibleFlow::phaseVolumeFraction >(); + subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); phaseVolFrac.setValues< parallelDevicePolicy<> >( phaseVolFrac ); arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const & phaseMass_n = - subRegion.template getField< fields::flow::immiscibleFlow::phaseMass_n >(); - + subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseMass_n >(); + arrayView2d< real64, immiscibleFlow::USD_PHASE > const & phaseMass = - subRegion.template getField< fields::flow::immiscibleFlow::phaseMass >(); + subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseMass >(); phaseMass.setValues< parallelDevicePolicy<> >( phaseMass_n ); if( m_isThermal ) @@ -772,8 +608,8 @@ void ImmiscibleMultiphaseFlow::resetStateToBeginningOfStep( DomainPartition & do } void ImmiscibleMultiphaseFlow::implicitStepComplete( real64 const & time, - real64 const & dt, - DomainPartition & domain ) + real64 const & dt, + DomainPartition & domain ) { // Step 1: save the converged aquifer state // note: we have to save the aquifer state **before** updating the pressure, @@ -788,13 +624,6 @@ void ImmiscibleMultiphaseFlow::implicitStepComplete( real64 const & time, [&]( localIndex const, ElementSubRegionBase & subRegion ) { - // update deltaPressure - arrayView1d< real64 const > const pres = subRegion.getField< fields::flow::pressure >(); - arrayView1d< real64 const > const initPres = subRegion.getField< fields::flow::initialPressure >(); - arrayView1d< real64 > const deltaPres = subRegion.getField< fields::flow::deltaPressure >(); - isothermalImmiscibleMultiphaseFlowKernels::StatisticsKernel:: - saveDeltaPressure< parallelDevicePolicy<> >( subRegion.size(), pres, initPres, deltaPres ); - // Step 3: save the converged solid state string const & solidName = subRegion.getReference< string >( viewKeyStruct::solidNamesString() ); CoupledSolidBase const & porousMaterial = getConstitutiveModel< CoupledSolidBase >( subRegion, solidName ); @@ -809,7 +638,7 @@ void ImmiscibleMultiphaseFlow::implicitStepComplete( real64 const & time, // Step 4: save converged state for the relperm model to handle hysteresis arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFrac = - subRegion.getField< fields::flow::immiscibleFlow::phaseVolumeFraction >(); + subRegion.getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); string const & relPermName = subRegion.getReference< string >( viewKeyStruct::relPermNamesString() ); RelativePermeabilityBase const & relPermMaterial = getConstitutiveModel< RelativePermeabilityBase >( subRegion, relPermName ); @@ -840,9 +669,9 @@ void ImmiscibleMultiphaseFlow::saveConvergedState( ElementSubRegionBase & subReg FlowSolverBase::saveConvergedState( subRegion ); arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFrac = - subRegion.getField< fields::flow::immiscibleFlow::phaseVolumeFraction >(); - arrayView2d< real64, immiscibleFlow::USD_PHASE > const phaseVolFrac_n = - subRegion.getField< fields::flow::immiscibleFlow::phaseVolumeFraction_n >(); + subRegion.getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); + arrayView2d< real64, immiscibleFlow::USD_PHASE > const phaseVolFrac_n = + subRegion.getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction_n >(); phaseVolFrac_n.setValues< parallelDevicePolicy<> >( phaseVolFrac ); @@ -853,7 +682,6 @@ void ImmiscibleMultiphaseFlow::updateState( DomainPartition & domain ) { GEOS_MARK_FUNCTION; - real64 maxDeltaPhaseVolFrac = 0.0; forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, MeshLevel & mesh, arrayView1d< string const > const & regionNames ) @@ -865,20 +693,9 @@ void ImmiscibleMultiphaseFlow::updateState( DomainPartition & domain ) // update porosity, permeability, and solid internal energy updatePorosityAndPermeability( subRegion ); // update all fluid properties - real64 const deltaPhaseVolFrac = updateFluidState( subRegion ); - maxDeltaPhaseVolFrac = LvArray::math::max( maxDeltaPhaseVolFrac, deltaPhaseVolFrac ); - // for thermal, update solid internal energy - if( m_isThermal ) - { - updateSolidInternalEnergyModel( subRegion ); - updateEnergy( subRegion ); - } + updateFluidState( subRegion ); } ); } ); - - maxDeltaPhaseVolFrac = MpiWrapper::max( maxDeltaPhaseVolFrac ); - - GEOS_LOG_LEVEL_RANK_0( 1, GEOS_FMT( " {}: Max phase volume fraction change = {}", getName(), fmt::format( "{:.{}f}", maxDeltaPhaseVolFrac, 4 ) ) ); } real64 ImmiscibleMultiphaseFlow::setNextDt( const geos::real64 & currentDt, geos::DomainPartition & domain ) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp index c49cd9b8ba8..3c6236afc70 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp @@ -42,7 +42,7 @@ class ImmiscibleMultiphaseFlow : public FlowSolverBase * @param parent the parent group of this instantiation of Group */ ImmiscibleMultiphaseFlow( const string & name, - Group * const parent ); + Group * const parent ); /// deleted default constructor ImmiscibleMultiphaseFlow() = delete; @@ -71,7 +71,7 @@ class ImmiscibleMultiphaseFlow : public FlowSolverBase /** * @copydoc SolverBase::getCatalogName() */ - string getCatalogName() const override { return catalogName(); } + string getCatalogName() const override { return catalogName(); } virtual void registerDataOnMesh( Group & meshBodies ) override final; @@ -104,32 +104,7 @@ class ImmiscibleMultiphaseFlow : public FlowSolverBase real64 const & dt, DomainPartition & domain ) override; - /** - * @brief Update all relevant fluid models using current values of pressure and phase volume fraction - * @param dataGroup the group storing the required fields - */ - void updateFluidModel( ObjectManagerBase & dataGroup ) const; - - /** - * @brief Update all relevant relperm models using current values of phase volume fraction - * @param dataGroup the group storing the required fields - */ - void updateRelPermModel( ObjectManagerBase & dataGroup ) const; - - /** - * @brief Update all relevant capillary pressure models using current values of phase volume fraction - * @param dataGroup the group storing the required fields - */ - void updateCapPressureModel( ObjectManagerBase & dataGroup ) const; - - - /** - * @brief Recompute phase mobility from constitutive and primary variables - * @param dataGroup the group storing the required field - */ - void updatePhaseMobility( ObjectManagerBase & dataGroup ) const; - - real64 updateFluidState( ElementSubRegionBase & subRegion ) const; + void updateFluidState( ElementSubRegionBase & subRegion ) const; virtual void saveConvergedState( ElementSubRegionBase & subRegion ) const override final; @@ -151,9 +126,9 @@ class ImmiscibleMultiphaseFlow : public FlowSolverBase * @param localRhs the system right-hand side vector */ void assembleAccumulationTerm( DomainPartition & domain, - DofManager const & dofManager, - CRSMatrixView< real64, globalIndex const > const & localMatrix, - arrayView1d< real64 > const & localRhs ) const; + DofManager const & dofManager, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) const; /** * @brief assembles the flux terms for all cells @@ -169,7 +144,7 @@ class ImmiscibleMultiphaseFlow : public FlowSolverBase DomainPartition const & domain, DofManager const & dofManager, CRSMatrixView< real64, globalIndex const > const & localMatrix, - arrayView1d< real64 > const & localRhs ) const override final; + arrayView1d< real64 > const & localRhs ) const; /** * @brief Initialize all variables from initial conditions * @param domain the domain containing the mesh and fields @@ -196,21 +171,6 @@ class ImmiscibleMultiphaseFlow : public FlowSolverBase CRSMatrixView< real64, globalIndex const > const & localMatrix, arrayView1d< real64 > const & localRhs ) const; - /** - * @brief Apply source flux boundary conditions to the system - * @param time current time - * @param dt time step - * @param dofManager degree-of-freedom manager associated with the linear system - * @param domain the domain - * @param localMatrix local system matrix - * @param localRhs local system right-hand side vector - */ - void applySourceFluxBC( real64 const time, - real64 const dt, - DofManager const & dofManager, - DomainPartition & domain, - CRSMatrixView< real64, globalIndex const > const & localMatrix, - arrayView1d< real64 > const & localRhs ) const; /** * @brief function to set the next time step size * @param[in] currentDt the current time step size @@ -222,12 +182,36 @@ class ImmiscibleMultiphaseFlow : public FlowSolverBase virtual void initializePostInitialConditionsPreSubGroups() override; -protected: +private: virtual void postInputInitialization() override; virtual void initializePreSubGroups() override; + /** + * @brief Update all relevant fluid models using current values of pressure and phase volume fraction + * @param dataGroup the group storing the required fields + */ + void updateFluidModel( ObjectManagerBase & dataGroup ) const; + + /** + * @brief Update all relevant relperm models using current values of phase volume fraction + * @param dataGroup the group storing the required fields + */ + void updateRelPermModel( ObjectManagerBase & dataGroup ) const; + + /** + * @brief Update all relevant capillary pressure models using current values of phase volume fraction + * @param dataGroup the group storing the required fields + */ + void updateCapPressureModel( ObjectManagerBase & dataGroup ) const; + + /** + * @brief Recompute phase mobility from constitutive and primary variables + * @param dataGroup the group storing the required field + */ + void updatePhaseMobility( ObjectManagerBase & dataGroup ) const; + /** * @brief Utility function that encapsulates the call to FieldSpecificationBase::applyFieldValue in BC application * @param[in] time_n the time at the beginning of the step @@ -251,6 +235,13 @@ class ImmiscibleMultiphaseFlow : public FlowSolverBase /// flag to determine whether or not to apply capillary pressure integer m_hasCapPressure; + struct viewKeyStruct : public FlowSolverBase::viewKeyStruct + { + static constexpr char const * capPressureNamesString() { return "capPressureNames"; } + static constexpr char const * relPermNamesString() { return "relPermNames"; } + static constexpr char const * elemDofFieldString() { return "elemDofField"; } + }; + private: virtual void setConstitutiveNames( ElementSubRegionBase & subRegion ) const override; @@ -259,11 +250,11 @@ class ImmiscibleMultiphaseFlow : public FlowSolverBase template< typename OBJECT_TYPE > void ImmiscibleMultiphaseFlow::applyFieldValue( real64 const & time_n, - real64 const & dt, - MeshLevel & mesh, - char const logMessage[], - string const fieldKey, - string const boundaryFieldKey ) const + real64 const & dt, + MeshLevel & mesh, + char const logMessage[], + string const fieldKey, + string const boundaryFieldKey ) const { FieldSpecificationManager & fsManager = FieldSpecificationManager::getInstance(); diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlowFields.hpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlowFields.hpp index abf3588f0eb..3cb4fc7a6df 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlowFields.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlowFields.hpp @@ -17,8 +17,8 @@ * @file CompositionalMultiphaseBaseFields.hpp */ -#ifndef GEOS_PHYSICSSOLVERS_FLUIDFLOW_COMPOSITIONALMULTIPHASEBASEFIELDS_HPP_ -#define GEOS_PHYSICSSOLVERS_FLUIDFLOW_COMPOSITIONALMULTIPHASEBASEFIELDS_HPP_ +#ifndef GEOS_PHYSICSSOLVERS_FLUIDFLOW_IMMISCIBLEMULTIPHASEFLOWFIELDS_HPP_ +#define GEOS_PHYSICSSOLVERS_FLUIDFLOW_IMMISCIBLEMULTIPHASEFLOWFIELDS_HPP_ #include "common/DataLayouts.hpp" #include "mesh/MeshFields.hpp" @@ -67,7 +67,7 @@ DECLARE_FIELD( phaseMass_n, 0, NOPLOT, WRITE_AND_READ, - "Phase mass at the previous converged time step" ); + "Phase mass at the previous converged time step" ); DECLARE_FIELD( phaseMobility, "phaseMobility", @@ -106,4 +106,4 @@ DECLARE_FIELD( phaseCFLNumber, } -#endif // GEOS_PHYSICSSOLVERS_FLUIDFLOW_COMPOSITIONALMULTIPHASEBASEFIELDS_HPP_ +#endif // GEOS_PHYSICSSOLVERS_FLUIDFLOW_IMMISCIBLEMULTIPHASEFLOWFIELDS_HPP_ diff --git a/src/coreComponents/physicsSolvers/fluidFlow/IsothermalCompositionalMultiphaseBaseKernels.hpp b/src/coreComponents/physicsSolvers/fluidFlow/IsothermalCompositionalMultiphaseBaseKernels.hpp index 108e5a9261a..61493575cd7 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/IsothermalCompositionalMultiphaseBaseKernels.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/IsothermalCompositionalMultiphaseBaseKernels.hpp @@ -26,6 +26,7 @@ #include "common/GEOS_RAJA_Interface.hpp" #include "constitutive/solid/CoupledSolidBase.hpp" #include "constitutive/fluid/multifluid/MultiFluidBase.hpp" +#include "constitutive/relativePermeability/layouts.hpp" #include "functions/TableFunction.hpp" #include "mesh/ElementSubRegionBase.hpp" #include "mesh/ObjectManagerBase.hpp" From 0d159ae1fafaba46a9543cf718585176c2c5ee52 Mon Sep 17 00:00:00 2001 From: Ryan Michael Aronson Date: Thu, 1 Aug 2024 11:12:39 -0700 Subject: [PATCH 006/102] update input file so it runs --- .../immiscible_2phaseFlow_1d.xml | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscible_2phaseFlow_1d.xml b/inputFiles/immiscibleMultiphaseFlow/immiscible_2phaseFlow_1d.xml index 0c928a15e2b..ecbf73253af 100644 --- a/inputFiles/immiscibleMultiphaseFlow/immiscible_2phaseFlow_1d.xml +++ b/inputFiles/immiscibleMultiphaseFlow/immiscible_2phaseFlow_1d.xml @@ -7,7 +7,8 @@ name="FlowSolver" discretization="TPFA" targetRegions="{ Domain }" - logLevel="1"> + logLevel="1" + temperature="300"> @@ -51,7 +52,7 @@ + target="/Solvers/FlowSolver"/> + materialList="{ water, rock, relperm }"/> @@ -101,6 +102,15 @@ + + + + From 7783a15411524b2d4b865f894442fb29e33e3af3 Mon Sep 17 00:00:00 2001 From: Ryan Michael Aronson Date: Thu, 1 Aug 2024 12:25:20 -0700 Subject: [PATCH 007/102] adding skeleton for setupDofs --- .../fluidFlow/ImmiscibleMultiphaseFlow.cpp | 28 +++++++++++++++++++ .../fluidFlow/ImmiscibleMultiphaseFlow.hpp | 4 +++ 2 files changed, 32 insertions(+) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp index 9a93fec7e66..48625cc4c3b 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp @@ -533,6 +533,34 @@ void ImmiscibleMultiphaseFlow::assembleFluxTerms( real64 const dt, GEOS_UNUSED_VAR( dt, domain, dofManager, localMatrix, localRhs ); } +// Ryan: Looks like this will need to be overwritten as well... +// I have left the CompositionalMultiphaseFVM implementation for reference +void ImmiscibleMultiphaseFlow::setupDofs( DomainPartition const & domain, + DofManager & dofManager ) const +{ + GEOS_UNUSED_VAR(domain, dofManager); + //// add a field for the cell-centered degrees of freedom + //dofManager.addField( viewKeyStruct::elemDofFieldString(), + // FieldLocation::Elem, + // m_numDofPerCell, + // getMeshTargets() ); + + //// this call with instruct GEOS to reorder the dof numbers + //dofManager.setLocalReorderingType( viewKeyStruct::elemDofFieldString(), + // DofManager::LocalReorderingType::ReverseCutHillMcKee ); + + //// for the volume balance equation, disable global coupling + //// this equation is purely local (not coupled to neighbors or other physics) + //dofManager.disableGlobalCouplingForEquation( viewKeyStruct::elemDofFieldString(), + // m_numComponents ); + + + //NumericalMethodsManager const & numericalMethodManager = domain.getNumericalMethodManager(); + //FiniteVolumeManager const & fvManager = numericalMethodManager.getFiniteVolumeManager(); + //FluxApproximationBase const & fluxApprox = fvManager.getFluxApproximation( m_discretizationName ); + //dofManager.addCoupling( viewKeyStruct::elemDofFieldString(), fluxApprox ); +} + void ImmiscibleMultiphaseFlow::applyBoundaryConditions( real64 const time_n, real64 const dt, DomainPartition & domain, diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp index 3c6236afc70..34d603abadb 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp @@ -88,6 +88,10 @@ class ImmiscibleMultiphaseFlow : public FlowSolverBase CRSMatrixView< real64, globalIndex const > const & localMatrix, arrayView1d< real64 > const & localRhs ) override; + virtual void + setupDofs( DomainPartition const & domain, + DofManager & dofManager ) const override; + virtual void applyBoundaryConditions( real64 const time_n, real64 const dt, From 5fcd5d8adc46530bcc479ff6c6c538f36670794c Mon Sep 17 00:00:00 2001 From: rpiazza87 Date: Wed, 31 Jul 2024 17:19:00 -0700 Subject: [PATCH 008/102] testing --- .../physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp index 48625cc4c3b..441c7ebc926 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp @@ -485,7 +485,7 @@ void ImmiscibleMultiphaseFlow::assembleSystem( real64 const GEOS_UNUSED_PARAM( t CRSMatrixView< real64, globalIndex const > const & localMatrix, arrayView1d< real64 > const & localRhs ) { - GEOS_MARK_FUNCTION; + GEOS_MARK_FUNCTION; // TODO Ralph assembleAccumulationTerm( domain, dofManager, From 8e132b9ac85c5890c623e76a47c5981b461274b3 Mon Sep 17 00:00:00 2001 From: rpiazza87 Date: Fri, 2 Aug 2024 08:58:20 -0700 Subject: [PATCH 009/102] fluid model --- .../fluidFlow/ImmiscibleMultiphaseFlow.cpp | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp index 441c7ebc926..a05d5ed652f 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp @@ -34,6 +34,8 @@ #include "constitutive/ConstitutivePassThru.hpp" +#include + #if defined( __INTEL_COMPILER ) #pragma GCC optimize "O0" #endif @@ -45,6 +47,48 @@ using namespace dataRepository; using namespace constitutive; using namespace fields::immiscibleMultiphaseFlow; +// Fluid model for isothermal T = 175 oC +double co2_viscosity(double P) +{ + P = P / 1000000; // check whether GEOS uses Pa or MPa + return ( -1.5596 * pow(10, -10) * pow(P, 3) + 1.94571 * pow(10, -8) * pow(P, 2) + 6.77304 * pow(10, -8) * P + 0.0000214166); // [Pa.s] +} + +double co2_dviscosity(double P) +{ + P = P / 1000000; // check whether GEOS uses Pa or MPa + return ( -4.6788 * pow(10, -10) * pow(P, 2) + 3.89142 * pow(10, -8) * P + 6.77304 * pow(10, -8)); +} + +double co2_density(double P) +{ + P = P / 1000000; // check whether GEOS uses Pa or MPa + return ( -0.0000126691 * pow(P, 3) - 0.118131 * pow(P, 2) + 19.6211 * P - 52.0635 ); +} + +double co2_ddensity(double P) +{ + P = P / 1000000; // check whether GEOS uses Pa or MPa + return ( -0.0000380073 * pow(P, 2) - 0.236262 * P + 19.6211 ); +} + +double water_viscosity(double P) { + return ( 0.000164 ); +} + +double water_dviscosity(double P) { + return ( 0.0 ); +} + +double water_density(double P) { + P = P / 1000000; // check whether GEOS uses Pa or MPa + return ( 0.55125 * P + 893.06044); +} + +double water_ddensity(double P) { + return ( 0.55125 ); +} + ImmiscibleMultiphaseFlow::ImmiscibleMultiphaseFlow( const string & name, Group * const parent ) : From c21d0474e02cd03a3d387968f05558751c6b4f88 Mon Sep 17 00:00:00 2001 From: rpiazza87 Date: Fri, 2 Aug 2024 09:44:45 -0700 Subject: [PATCH 010/102] rock-fluid model --- .../fluidFlow/ImmiscibleMultiphaseFlow.cpp | 45 ++++++++++++++++--- 1 file changed, 38 insertions(+), 7 deletions(-) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp index a05d5ed652f..a5654480c27 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp @@ -57,36 +57,67 @@ double co2_viscosity(double P) double co2_dviscosity(double P) { P = P / 1000000; // check whether GEOS uses Pa or MPa - return ( -4.6788 * pow(10, -10) * pow(P, 2) + 3.89142 * pow(10, -8) * P + 6.77304 * pow(10, -8)); + return ( -4.6788 * pow(10, -10) * pow(P, 2) + 3.89142 * pow(10, -8) * P + 6.77304 * pow(10, -8)); // [Pa.s/MPa] } double co2_density(double P) { P = P / 1000000; // check whether GEOS uses Pa or MPa - return ( -0.0000126691 * pow(P, 3) - 0.118131 * pow(P, 2) + 19.6211 * P - 52.0635 ); + return ( -0.0000126691 * pow(P, 3) - 0.118131 * pow(P, 2) + 19.6211 * P - 52.0635 ); // [kg/m3] } double co2_ddensity(double P) { P = P / 1000000; // check whether GEOS uses Pa or MPa - return ( -0.0000380073 * pow(P, 2) - 0.236262 * P + 19.6211 ); + return ( -0.0000380073 * pow(P, 2) - 0.236262 * P + 19.6211 ); // [kg/m3.MPa] } double water_viscosity(double P) { - return ( 0.000164 ); + return ( 0.000164 ); // [Pa.s] } double water_dviscosity(double P) { - return ( 0.0 ); + return ( 0.0 ); // [Pa.s/MPa] } double water_density(double P) { P = P / 1000000; // check whether GEOS uses Pa or MPa - return ( 0.55125 * P + 893.06044); + return ( 0.55125 * P + 893.06044); // [kg/m3] } double water_ddensity(double P) { - return ( 0.55125 ); + return ( 0.55125 ); // [kg/m3.MPa] +} + +// Rock-Fluid model +double co2_relperm(double S) +{ + return ( pow(1 - S, 2) ); // [-] +} + +double co2_drelperm(double S) +{ + return ( 2 * (1 - S) ); // [-] +} + +double water_relperm(double S) +{ + return ( pow(S, 6) ); // [-] +} + +double water_drelperm(double S) +{ + return ( 6 * pow(S, 5) ); // [-] +} + +double co2_cappress(double S) +{ + return ( 0.00049309 * pow(S, -2.34806) ); // [MPa] check whether GEOS uses Pa or MPa +} + +double co2_dcappress(double S) +{ + return ( -0.00021 * pow(S, -1.34806) ); // [MPa] check whether GEOS uses Pa or MPa } ImmiscibleMultiphaseFlow::ImmiscibleMultiphaseFlow( const string & name, From d59fa4ef7c4ed92dca2702f9bed2a07cceab5597 Mon Sep 17 00:00:00 2001 From: rpiazza87 Date: Tue, 6 Aug 2024 18:08:51 -0700 Subject: [PATCH 011/102] new kernel file --- .../fluidFlow/ImmiscibleMultiphaseFlow.cpp | 99 +++++-- .../fluidFlow/ImmiscibleMultiphaseKernels.hpp | 246 ++++++++++++++++++ 2 files changed, 324 insertions(+), 21 deletions(-) create mode 100644 src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseKernels.hpp diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp index a5654480c27..507ab656c42 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp @@ -21,6 +21,7 @@ #include "FlowSolverBaseFields.hpp" #include "physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlowFields.hpp" +#include "physicsSolvers/fluidFlow/ImmiscibleMultiphaseKernels.hpp" #include "physicsSolvers/fluidFlow/IsothermalCompositionalMultiphaseBaseKernels.hpp" #include "physicsSolvers/fluidFlow/IsothermalCompositionalMultiphaseFVMKernels.hpp" @@ -48,74 +49,78 @@ using namespace constitutive; using namespace fields::immiscibleMultiphaseFlow; // Fluid model for isothermal T = 175 oC -double co2_viscosity(double P) +real64 co2_viscosity(real64 P) { - P = P / 1000000; // check whether GEOS uses Pa or MPa + P = P / 1000000.0; // check whether GEOS uses Pa or MPa return ( -1.5596 * pow(10, -10) * pow(P, 3) + 1.94571 * pow(10, -8) * pow(P, 2) + 6.77304 * pow(10, -8) * P + 0.0000214166); // [Pa.s] } -double co2_dviscosity(double P) +real64 co2_dviscosity(real64 P) { - P = P / 1000000; // check whether GEOS uses Pa or MPa + P = P / 1000000.0; // check whether GEOS uses Pa or MPa return ( -4.6788 * pow(10, -10) * pow(P, 2) + 3.89142 * pow(10, -8) * P + 6.77304 * pow(10, -8)); // [Pa.s/MPa] } -double co2_density(double P) +real64 co2_density(real64 P) { - P = P / 1000000; // check whether GEOS uses Pa or MPa + P = P / 1000000.0; // check whether GEOS uses Pa or MPa return ( -0.0000126691 * pow(P, 3) - 0.118131 * pow(P, 2) + 19.6211 * P - 52.0635 ); // [kg/m3] } -double co2_ddensity(double P) +real64 co2_ddensity(real64 P) { - P = P / 1000000; // check whether GEOS uses Pa or MPa + P = P / 1000000.0; // check whether GEOS uses Pa or MPa return ( -0.0000380073 * pow(P, 2) - 0.236262 * P + 19.6211 ); // [kg/m3.MPa] } -double water_viscosity(double P) { +real64 water_viscosity(real64 P) +{ return ( 0.000164 ); // [Pa.s] } -double water_dviscosity(double P) { +real64 water_dviscosity(real64 P) +{ return ( 0.0 ); // [Pa.s/MPa] } -double water_density(double P) { - P = P / 1000000; // check whether GEOS uses Pa or MPa +real64 water_density(real64 P) +{ + P = P / 1000000.0; // check whether GEOS uses Pa or MPa return ( 0.55125 * P + 893.06044); // [kg/m3] } -double water_ddensity(double P) { +real64 water_ddensity(real64 P) +{ return ( 0.55125 ); // [kg/m3.MPa] } // Rock-Fluid model -double co2_relperm(double S) +real64 co2_relperm(real64 S) { return ( pow(1 - S, 2) ); // [-] } -double co2_drelperm(double S) +real64 co2_drelperm(real64 S) { - return ( 2 * (1 - S) ); // [-] + return ( 2.0 * (1 - S) ); // [-] } -double water_relperm(double S) +real64 water_relperm(real64 S) { return ( pow(S, 6) ); // [-] } -double water_drelperm(double S) +real64 water_drelperm(real64 S) { - return ( 6 * pow(S, 5) ); // [-] + return ( 6.0 * pow(S, 5) ); // [-] } -double co2_cappress(double S) +real64 co2_cappress(real64 S) { return ( 0.00049309 * pow(S, -2.34806) ); // [MPa] check whether GEOS uses Pa or MPa } -double co2_dcappress(double S) +real64 co2_dcappress(real64 S) { return ( -0.00021 * pow(S, -1.34806) ); // [MPa] check whether GEOS uses Pa or MPa } @@ -606,6 +611,58 @@ void ImmiscibleMultiphaseFlow::assembleFluxTerms( real64 const dt, arrayView1d< real64 > const & localRhs ) const { GEOS_UNUSED_VAR( dt, domain, dofManager, localMatrix, localRhs ); + + GEOS_MARK_FUNCTION; + + NumericalMethodsManager const & numericalMethodManager = domain.getNumericalMethodManager(); + FiniteVolumeManager const & fvManager = numericalMethodManager.getFiniteVolumeManager(); + FluxApproximationBase const & fluxApprox = fvManager.getFluxApproximation( m_discretizationName ); + + string const & dofKey = dofManager.getKey( viewKeyStruct::elemDofFieldString() ); + + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&] ( string const &, + MeshLevel const & mesh, + arrayView1d< string const > const & ) + { + fluxApprox.forAllStencils( mesh, [&]( auto & stencil ) + { + FaceBasedAssemblyKernelFactory::createAndLaunch< parallelDevicePolicy<> >( dofManager.rankOffset(), + dofKey, + getName(), + mesh.getElemManager(), + stencilWrapper, + dt, + localMatrix.toViewConstSizes(), + localRhs.toView() ); + } ); + } ); + +} + +void ImmiscibleMultiphaseFlow::setupDofs( DomainPartition const & domain, + DofManager & dofManager ) const +{ + GEOS_UNUSED_VAR(domain, dofManager); + //// add a field for the cell-centered degrees of freedom + //dofManager.addField( viewKeyStruct::elemDofFieldString(), + // FieldLocation::Elem, + // m_numDofPerCell, + // getMeshTargets() ); + + //// this call with instruct GEOS to reorder the dof numbers + //dofManager.setLocalReorderingType( viewKeyStruct::elemDofFieldString(), + // DofManager::LocalReorderingType::ReverseCutHillMcKee ); + + //// for the volume balance equation, disable global coupling + //// this equation is purely local (not coupled to neighbors or other physics) + //dofManager.disableGlobalCouplingForEquation( viewKeyStruct::elemDofFieldString(), + // m_numComponents ); + + + //NumericalMethodsManager const & numericalMethodManager = domain.getNumericalMethodManager(); + //FiniteVolumeManager const & fvManager = numericalMethodManager.getFiniteVolumeManager(); + //FluxApproximationBase const & fluxApprox = fvManager.getFluxApproximation( m_discretizationName ); + //dofManager.addCoupling( viewKeyStruct::elemDofFieldString(), fluxApprox ); } // Ryan: Looks like this will need to be overwritten as well... diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseKernels.hpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseKernels.hpp new file mode 100644 index 00000000000..c098607d6fa --- /dev/null +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseKernels.hpp @@ -0,0 +1,246 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * SPDX-License-Identifier: LGPL-2.1-only + * + * Copyright (c) 2018-2020 Lawrence Livermore National Security LLC + * Copyright (c) 2018-2020 The Board of Trustees of the Leland Stanford Junior University + * Copyright (c) 2018-2020 TotalEnergies + * Copyright (c) 2019- GEOSX Contributors + * All rights reserved + * + * See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details. + * ------------------------------------------------------------------------------------------------------------ + */ + +/** + * @file ImmiscibleMultiphaseKernels.hpp + */ + +#ifndef GEOS_PHYSICSSOLVERS_FLUIDFLOW_MULTIPHASEKERNELS_HPP +#define GEOS_PHYSICSSOLVERS_FLUIDFLOW_MULTIPHASEKERNELS_HPP + +#include "common/DataLayouts.hpp" +#include "common/DataTypes.hpp" +#include "common/GEOS_RAJA_Interface.hpp" +#include "constitutive/fluid/singlefluid/SingleFluidBase.hpp" +#include "constitutive/fluid/singlefluid/SingleFluidFields.hpp" +#include "constitutive/fluid/singlefluid/SlurryFluidBase.hpp" +#include "constitutive/fluid/singlefluid/SlurryFluidFields.hpp" +#include "constitutive/permeability/PermeabilityBase.hpp" +#include "constitutive/permeability/PermeabilityFields.hpp" +#include "fieldSpecification/AquiferBoundaryCondition.hpp" +#include "finiteVolume/BoundaryStencil.hpp" +#include "finiteVolume/FluxApproximationBase.hpp" +#include "linearAlgebra/interfaces/InterfaceTypes.hpp" +#include "physicsSolvers/fluidFlow/FlowSolverBaseFields.hpp" +#include "physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlowFields.hpp" +#include "physicsSolvers/fluidFlow/SinglePhaseBaseKernels.hpp" // create for multiphase +#include "physicsSolvers/fluidFlow/StencilAccessors.hpp" + +namespace geos +{ + +namespace immiscibleMultiphaseKernels +{ +using namespace constitutive; + + +/******************************** FaceBasedAssemblyKernelBase ********************************/ + +/** + * @brief Base class for FaceBasedAssemblyKernel that holds all data not dependent + * on template parameters (like stencil type and number of dofs). + */ +class FaceBasedAssemblyKernelBase +{ +public: + + /** + * @brief The type for element-based data. Consists entirely of ArrayView's. + * + * Can be converted from ElementRegionManager::ElementViewConstAccessor + * by calling .toView() or .toViewConst() on an accessor instance + */ + template< typename VIEWTYPE > + using ElementViewConst = ElementRegionManager::ElementViewConst< VIEWTYPE >; + + using DofNumberAccessor = ElementRegionManager::ElementViewAccessor< arrayView1d< globalIndex const > >; + + using ImmiscibleMultiphaseFlowAccessors = + StencilAccessors< fields::ghostRank, + fields::flow::pressure, + fields::flow::pressure_n, + fields::flow::gravityCoefficient, + fields::flow::mobility, + fields::flow::dMobility_dPressure >; + + using ImmiscibleMultiphaseFluidAccessors = + StencilMaterialAccessors< SingleFluidBase, + fields::singlefluid::density, + fields::singlefluid::dDensity_dPressure >; + + using SlurryFluidAccessors = + StencilMaterialAccessors< SlurryFluidBase, + fields::singlefluid::density, + fields::singlefluid::dDensity_dPressure >; + + using PermeabilityAccessors = + StencilMaterialAccessors< PermeabilityBase, + fields::permeability::permeability, + fields::permeability::dPerm_dPressure >; + + using ProppantPermeabilityAccessors = + StencilMaterialAccessors< PermeabilityBase, + fields::permeability::permeability, + fields::permeability::dPerm_dPressure, + fields::permeability::dPerm_dDispJump, + fields::permeability::permeabilityMultiplier >; + + /** + * @brief Constructor for the kernel interface + * @param[in] rankOffset the offset of my MPI rank + * @param[in] dofNumberAccessor accessor for the dof numbers + * @param[in] singleFlowAccessors accessor for wrappers registered by the solver + * @param[in] singlePhaseFluidAccessors accessor for wrappers registered by the singlefluid model + * @param[in] permeabilityAccessors accessor for wrappers registered by the permeability model + * @param[in] dt time step size + * @param[inout] localMatrix the local CRS matrix + * @param[inout] localRhs the local right-hand side vector + */ + FaceBasedAssemblyKernelBase( globalIndex const rankOffset, + DofNumberAccessor const & dofNumberAccessor, + ImmiscibleMultiphaseFlowAccessors const & singlePhaseFlowAccessors, + ImmiscibleMultiphaseFluidAccessors const & singlePhaseFluidAccessors, + PermeabilityAccessors const & permeabilityAccessors, + real64 const & dt, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) + : m_rankOffset( rankOffset ), + m_dt( dt ), + m_dofNumber( dofNumberAccessor.toNestedViewConst() ), + m_permeability( permeabilityAccessors.get( fields::permeability::permeability {} ) ), + m_dPerm_dPres( permeabilityAccessors.get( fields::permeability::dPerm_dPressure {} ) ), + m_ghostRank( singlePhaseFlowAccessors.get( fields::ghostRank {} ) ), + m_gravCoef( singlePhaseFlowAccessors.get( fields::flow::gravityCoefficient {} ) ), + m_pres( singlePhaseFlowAccessors.get( fields::flow::pressure {} ) ), + m_mob( singlePhaseFlowAccessors.get( fields::flow::mobility {} ) ), + m_dMob_dPres( singlePhaseFlowAccessors.get( fields::flow::dMobility_dPressure {} ) ), + m_dens( singlePhaseFluidAccessors.get( fields::singlefluid::density {} ) ), + m_dDens_dPres( singlePhaseFluidAccessors.get( fields::singlefluid::dDensity_dPressure {} ) ), + m_localMatrix( localMatrix ), + m_localRhs( localRhs ) + {} + +protected: + + /// Offset for my MPI rank + globalIndex const m_rankOffset; + + /// Time step size + real64 const m_dt; + + /// Views on dof numbers + ElementViewConst< arrayView1d< globalIndex const > > const m_dofNumber; + + /// Views on permeability + ElementViewConst< arrayView3d< real64 const > > m_permeability; + ElementViewConst< arrayView3d< real64 const > > m_dPerm_dPres; + + /// Views on ghost rank numbers and gravity coefficients + ElementViewConst< arrayView1d< integer const > > const m_ghostRank; + ElementViewConst< arrayView1d< real64 const > > const m_gravCoef; + + // Primary and secondary variables + /// Views on pressure + ElementViewConst< arrayView1d< real64 const > > const m_pres; + + /// Views on fluid mobility + ElementViewConst< arrayView1d< real64 const > > const m_mob; + ElementViewConst< arrayView1d< real64 const > > const m_dMob_dPres; + + /// Views on fluid density + ElementViewConst< arrayView2d< real64 const > > const m_dens; + ElementViewConst< arrayView2d< real64 const > > const m_dDens_dPres; + + // Residual and jacobian + + /// View on the local CRS matrix + CRSMatrixView< real64, globalIndex const > const m_localMatrix; + /// View on the local RHS + arrayView1d< real64 > const m_localRhs; +}; + + + + + + + + + + + + + + + + + + +/** + * @class FaceBasedAssemblyKernelFactory + */ +class FaceBasedAssemblyKernelFactory +{ +public: + + /** + * @brief Create a new kernel and launch + * @tparam POLICY the policy used in the RAJA kernel + * @tparam STENCILWRAPPER the type of the stencil wrapper + * @param[in] rankOffset the offset of my MPI rank + * @param[in] dofKey string to get the element degrees of freedom numbers + * @param[in] solverName name of the solver (to name accessors) + * @param[in] elemManager reference to the element region manager + * @param[in] stencilWrapper reference to the stencil wrapper + * @param[in] dt time step size + * @param[inout] localMatrix the local CRS matrix + * @param[inout] localRhs the local right-hand side vector + */ + template< typename POLICY, typename STENCILWRAPPER > + static void + createAndLaunch( globalIndex const rankOffset, + string const & dofKey, + string const & solverName, + ElementRegionManager const & elemManager, + STENCILWRAPPER const & stencilWrapper, + real64 const & dt, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) + { + integer constexpr NUM_EQN = 1; + integer constexpr NUM_DOF = 1; + + ElementRegionManager::ElementViewAccessor< arrayView1d< globalIndex const > > dofNumberAccessor = + elemManager.constructArrayViewAccessor< globalIndex, 1 >( dofKey ); + dofNumberAccessor.setName( solverName + "/accessors/" + dofKey ); + + using kernelType = FaceBasedAssemblyKernel< NUM_EQN, NUM_DOF, STENCILWRAPPER >; + typename kernelType::SinglePhaseFlowAccessors flowAccessors( elemManager, solverName ); + typename kernelType::SinglePhaseFluidAccessors fluidAccessors( elemManager, solverName ); + typename kernelType::PermeabilityAccessors permAccessors( elemManager, solverName ); + + kernelType kernel( rankOffset, stencilWrapper, dofNumberAccessor, + flowAccessors, fluidAccessors, permAccessors, + dt, localMatrix, localRhs ); + kernelType::template launch< POLICY >( stencilWrapper.size(), kernel ); + } +}; + + + + +} // namesace immiscible multiphasekernels + + +} // namespace geos \ No newline at end of file From 1fe657043a19696fada2b06e49b51c72f967a18f Mon Sep 17 00:00:00 2001 From: rpiazza87 Date: Mon, 12 Aug 2024 00:33:37 -0700 Subject: [PATCH 012/102] updated kernel functions --- .../fluidFlow/ImmiscibleMultiphaseKernels.hpp | 579 ++++++++++++++++-- 1 file changed, 534 insertions(+), 45 deletions(-) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseKernels.hpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseKernels.hpp index c098607d6fa..c6f1a05c868 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseKernels.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseKernels.hpp @@ -22,7 +22,7 @@ #include "common/DataLayouts.hpp" #include "common/DataTypes.hpp" #include "common/GEOS_RAJA_Interface.hpp" -#include "constitutive/fluid/singlefluid/SingleFluidBase.hpp" +#include "constitutive/fluid/singlefluid/SingleFluidBase.hpp" // get correct fluid model #include "constitutive/fluid/singlefluid/SingleFluidFields.hpp" #include "constitutive/fluid/singlefluid/SlurryFluidBase.hpp" #include "constitutive/fluid/singlefluid/SlurryFluidFields.hpp" @@ -34,7 +34,7 @@ #include "linearAlgebra/interfaces/InterfaceTypes.hpp" #include "physicsSolvers/fluidFlow/FlowSolverBaseFields.hpp" #include "physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlowFields.hpp" -#include "physicsSolvers/fluidFlow/SinglePhaseBaseKernels.hpp" // create for multiphase +#include "physicsSolvers/fluidFlow/SinglePhaseBaseKernels.hpp" // create for multiphase for kernels #include "physicsSolvers/fluidFlow/StencilAccessors.hpp" namespace geos @@ -70,69 +70,79 @@ class FaceBasedAssemblyKernelBase StencilAccessors< fields::ghostRank, fields::flow::pressure, fields::flow::pressure_n, + fields::flow::phaseVolumeFraction, + fields::flow::phaseVolumeFraction_n, fields::flow::gravityCoefficient, - fields::flow::mobility, - fields::flow::dMobility_dPressure >; + fields::flow::phaseMobility, + fields::flow::dPhaseMobility >; // TODO: fix derivatives of mobility using ImmiscibleMultiphaseFluidAccessors = - StencilMaterialAccessors< SingleFluidBase, - fields::singlefluid::density, - fields::singlefluid::dDensity_dPressure >; + StencilMaterialAccessors< MultiFluidBase, + fields::multifluid::phaseDensity, + fields::multifluid::dPhaseDensity >; - using SlurryFluidAccessors = - StencilMaterialAccessors< SlurryFluidBase, - fields::singlefluid::density, - fields::singlefluid::dDensity_dPressure >; + using CapPressureAccessors = + StencilMaterialAccessors< CapillaryPressureBase, + fields::cappres::phaseCapPressure, + fields::cappres::dPhaseCapPressure_dPhaseVolFraction >; using PermeabilityAccessors = StencilMaterialAccessors< PermeabilityBase, fields::permeability::permeability, - fields::permeability::dPerm_dPressure >; - - using ProppantPermeabilityAccessors = - StencilMaterialAccessors< PermeabilityBase, - fields::permeability::permeability, - fields::permeability::dPerm_dPressure, - fields::permeability::dPerm_dDispJump, - fields::permeability::permeabilityMultiplier >; + fields::permeability::dPerm_dPressure >; /** * @brief Constructor for the kernel interface + * @param[in] numPhases the number of fluid phases * @param[in] rankOffset the offset of my MPI rank * @param[in] dofNumberAccessor accessor for the dof numbers - * @param[in] singleFlowAccessors accessor for wrappers registered by the solver - * @param[in] singlePhaseFluidAccessors accessor for wrappers registered by the singlefluid model + * @param[in] multiPhaseFlowAccessors accessor for wrappers registered by the solver + * @param[in] multiPhaseFluidAccessors accessor for wrappers registered by the multiphase fluid model + * @param[in] capPressureAccessors accessor for wrappers registered by the capillary pressure model * @param[in] permeabilityAccessors accessor for wrappers registered by the permeability model * @param[in] dt time step size * @param[inout] localMatrix the local CRS matrix * @param[inout] localRhs the local right-hand side vector */ - FaceBasedAssemblyKernelBase( globalIndex const rankOffset, + FaceBasedAssemblyKernelBase( integer const numPhases, + globalIndex const rankOffset, DofNumberAccessor const & dofNumberAccessor, - ImmiscibleMultiphaseFlowAccessors const & singlePhaseFlowAccessors, - ImmiscibleMultiphaseFluidAccessors const & singlePhaseFluidAccessors, + ImmiscibleMultiphaseFlowAccessors const & multiPhaseFlowAccessors, + ImmiscibleMultiphaseFluidAccessors const & multiPhaseFluidAccessors, + CapPressureAccessors const & capPressureAccessors, PermeabilityAccessors const & permeabilityAccessors, real64 const & dt, CRSMatrixView< real64, globalIndex const > const & localMatrix, - arrayView1d< real64 > const & localRhs ) - : m_rankOffset( rankOffset ), + arrayView1d< real64 > const & localRhs, + integer const hasCapPressure, + integer const useTotalMassEquation ) + : m_numPhases (numPhases), + m_rankOffset( rankOffset ), m_dt( dt ), m_dofNumber( dofNumberAccessor.toNestedViewConst() ), m_permeability( permeabilityAccessors.get( fields::permeability::permeability {} ) ), m_dPerm_dPres( permeabilityAccessors.get( fields::permeability::dPerm_dPressure {} ) ), - m_ghostRank( singlePhaseFlowAccessors.get( fields::ghostRank {} ) ), - m_gravCoef( singlePhaseFlowAccessors.get( fields::flow::gravityCoefficient {} ) ), - m_pres( singlePhaseFlowAccessors.get( fields::flow::pressure {} ) ), - m_mob( singlePhaseFlowAccessors.get( fields::flow::mobility {} ) ), - m_dMob_dPres( singlePhaseFlowAccessors.get( fields::flow::dMobility_dPressure {} ) ), - m_dens( singlePhaseFluidAccessors.get( fields::singlefluid::density {} ) ), - m_dDens_dPres( singlePhaseFluidAccessors.get( fields::singlefluid::dDensity_dPressure {} ) ), + m_ghostRank( multiPhaseFlowAccessors.get( fields::ghostRank {} ) ), + m_gravCoef( multiPhaseFlowAccessors.get( fields::flow::gravityCoefficient {} ) ), + m_pres( multiPhaseFlowAccessors.get( fields::flow::pressure {} ) ), + m_mob( multiPhaseFlowAccessors.get( fields::flow::phaseMobility {} ) ), + m_dMob_dPres( multiPhaseFlowAccessors.get( fields::flow::dPhaseMobility {} ) ), + m_dMob_dSat( multiPhaseFlowAccessors.get( fields::flow::dPhaseMobility {} ) ), + m_dens( multiPhaseFluidAccessors.get( fields::multifluid::phaseDensity {} ) ), + m_dDens_dPres( multiPhaseFluidAccessors.get( fields::multifluid::dPhaseDensity {} ) ), + m_phaseCapPressure( capPressureAccessors.get( fields::cappres::phaseCapPressure {} ) ), + m_dPhaseCapPressure_dPhaseVolFrac( capPressureAccessors.get( fields::cappres::dPhaseCapPressure_dPhaseVolFraction {} ) ), m_localMatrix( localMatrix ), - m_localRhs( localRhs ) + m_localRhs( localRhs ), + m_hasCapPressure ( hasCapPressure ), + m_useTotalMassEquation ( useTotalMassEquation ) {} protected: + /// Number of fluid phases + integer const m_numPhases; + /// Offset for my MPI rank globalIndex const m_rankOffset; @@ -153,39 +163,512 @@ class FaceBasedAssemblyKernelBase // Primary and secondary variables /// Views on pressure ElementViewConst< arrayView1d< real64 const > > const m_pres; + /// Views on saturation + ElementViewConst< arrayView1d< real64 const > > const m_phaseVolFraction; /// Views on fluid mobility - ElementViewConst< arrayView1d< real64 const > > const m_mob; - ElementViewConst< arrayView1d< real64 const > > const m_dMob_dPres; + ElementViewConst< arrayView2d< real64 const > > const m_mob; + ElementViewConst< arrayView2d< real64 const > > const m_dMob_dPres; + ElementViewConst< arrayView2d< real64 const > > const m_dMob_dSat; /// Views on fluid density ElementViewConst< arrayView2d< real64 const > > const m_dens; ElementViewConst< arrayView2d< real64 const > > const m_dDens_dPres; + /// Views on capillary pressure + ElementViewConst< arrayView2d< real64 const > > const m_phaseCapPressure; + ElementViewConst< arrayView2d< real64 const > > const m_dPhaseCapPressure_dPhaseVolFrac; + // Residual and jacobian /// View on the local CRS matrix CRSMatrixView< real64, globalIndex const > const m_localMatrix; /// View on the local RHS arrayView1d< real64 > const m_localRhs; + + // Flags + integer const m_hasCapPressure; + integer const m_useTotalMassEquation; }; +/***************************************** */ +/** + * @class FaceBasedAssemblyKernel + * @tparam NUM_DOF number of degrees of freedom + * @tparam STENCILWRAPPER the type of the stencil wrapper + * @brief Define the interface for the assembly kernel in charge of flux terms + */ +template< integer NUM_EQN, integer NUM_DOF, typename STENCILWRAPPER > +class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase +{ +public: + /// Compute time value for the number of degrees of freedom + static constexpr integer numDof = NUM_DOF; + /// Compute time value for the number of equations + static constexpr integer numEqn = NUM_EQN; + /// Maximum number of elements at the face + static constexpr localIndex maxNumElems = STENCILWRAPPER::maxNumPointsInFlux; + /// Maximum number of connections at the face + static constexpr localIndex maxNumConns = STENCILWRAPPER::maxNumConnections; + /// Maximum number of points in the stencil + static constexpr localIndex maxStencilSize = STENCILWRAPPER::maxStencilSize; + /** + * @brief Constructor for the kernel interface + * @param[in] rankOffset the offset of my MPI rank + * @param[in] stencilWrapper reference to the stencil wrapper + * @param[in] dofNumberAccessor + * @param[in] singlePhaseFlowAccessors + * @param[in] singlePhaseFluidAccessors + * @param[in] capPressureAccessors + * @param[in] permeabilityAccessors + * @param[in] dt time step size + * @param[inout] localMatrix the local CRS matrix + * @param[inout] localRhs the local right-hand side vector + * @param[in] hasCapPressure flags for capillary pressure + * @param[in] useTotalMassEquation flags for using total velocity formulation + */ + FaceBasedAssemblyKernel( integer const numPhases, + globalIndex const rankOffset, + STENCILWRAPPER const & stencilWrapper, + DofNumberAccessor const & dofNumberAccessor, + ImmiscibleMultiphaseFlowAccessors const & multiPhaseFlowAccessors, + ImmiscibleMultiphaseFluidAccessors const & multiPhaseFluidAccessors, + CapPressureAccessors const & capPressureAccessors, + PermeabilityAccessors const & permeabilityAccessors, + real64 const & dt, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs, + integer const hasCapPressure, + integer const useTotalMassEquation ) + : FaceBasedAssemblyKernelBase( numPhases, + rankOffset, + dofNumberAccessor, + multiPhaseFlowAccessors, + multiPhaseFluidAccessors, + capPressureAccessors, + permeabilityAccessors, + dt, + localMatrix, + localRhs, + hasCapPressure, + useTotalMassEquation ), + m_stencilWrapper( stencilWrapper ), + m_seri( stencilWrapper.getElementRegionIndices() ), + m_sesri( stencilWrapper.getElementSubRegionIndices() ), + m_sei( stencilWrapper.getElementIndices() ) + {} + + /** + * @struct StackVariables + * @brief Kernel variables (dof numbers, jacobian and residual) located on the stack + */ + struct StackVariables + { + public: + /** + * @brief Constructor for the stack variables + * @param[in] size size of the stencil for this connection + * @param[in] numElems number of elements for this connection + */ + GEOS_HOST_DEVICE + StackVariables( localIndex const size, localIndex numElems ) + : stencilSize( size ), + numFluxElems( numElems ), + dofColIndices( size * numDof ), + localFlux( numElems * numEqn ), + localFluxJacobian( numElems * numEqn, size * numDof ) + {} + // Stencil information + /// Stencil size for a given connection + localIndex const stencilSize; + /// Number of elements for a given connection + localIndex const numFluxElems; + // Transmissibility and derivatives + /// Transmissibility + real64 transmissibility[maxNumConns][2]{}; + /// Derivatives of transmissibility with respect to pressure + real64 dTrans_dPres[maxNumConns][2]{}; + // Local degrees of freedom and local residual/jacobian + /// Indices of the matrix rows/columns corresponding to the dofs in this face + stackArray1d< globalIndex, maxNumElems * numDof > dofColIndices; + /// Storage for the face local residual vector (all equations except volume balance) + stackArray1d< real64, maxNumElems * numEqn > localFlux; + /// Storage for the face local Jacobian matrix + stackArray2d< real64, maxNumElems * numEqn * maxStencilSize * numDof > localFluxJacobian; + }; + + /** + * @brief Getter for the stencil size at this connection + * @param[in] iconn the connection index + * @return the size of the stencil at this connection + */ + GEOS_HOST_DEVICE + localIndex stencilSize( localIndex const iconn ) const + { return m_sei[iconn].size(); } + + /** + * @brief Getter for the number of elements at this connection + * @param[in] iconn the connection index + * @return the number of elements at this connection + */ + GEOS_HOST_DEVICE + localIndex numPointsInFlux( localIndex const iconn ) const + { return m_stencilWrapper.numPointsInFlux( iconn ); } + + /** + * @brief Performs the setup phase for the kernel. + * @param[in] iconn the connection index + * @param[in] stack the stack variables + */ + + GEOS_HOST_DEVICE + void setup( localIndex const iconn, + StackVariables & stack ) const + { + // set degrees of freedom indices for this face + for( integer i = 0; i < stack.stencilSize; ++i ) + { + globalIndex const offset = m_dofNumber[m_seri( iconn, i )][m_sesri( iconn, i )][m_sei( iconn, i )]; + + for( integer jdof = 0; jdof < numDof; ++jdof ) + { + stack.dofColIndices[i * numDof + jdof] = offset + jdof; + } + } + } + + /** + * @brief Compute the local flux contributions to the residual and Jacobian + * @tparam FUNC the type of the function that can be used to customize the computation of the flux + * @param[in] iconn the connection index + * @param[inout] stack the stack variables + * @param[in] NoOpFunc the function used to customize the computation of the flux + */ + template< typename FUNC = multiPhaseBaseKernels::NoOpFunc > + GEOS_HOST_DEVICE + void computeFlux( localIndex const iconn, + StackVariables & stack, + FUNC && kernelOp = singlePhaseBaseKernels::NoOpFunc{} ) const + { + // first, compute the transmissibilities at this face // get k and dk/dP from global arrays and place in stack + m_stencilWrapper.computeWeights( iconn, + m_permeability, + m_dPerm_dPres, + stack.transmissibility, + stack.dTrans_dPres ); + + localIndex k[2]; + localIndex connectionIndex = 0; + + for( k[0] = 0; k[0] < stack.numFluxElems; ++k[0] ) + { + for( k[1] = k[0] + 1; k[1] < stack.numFluxElems; ++k[1] ) + { + // clear working arrays + real64 densMean[m_numPhases]{}; + real64 dDensMean_dP[m_numPhases][2]{}; + // real64 densMean = 0.0; + // real64 dDensMean_dP[2]{0.0, 0.0}; + + real64 presGrad[m_numPhases]{}; /// check need for vector + real64 dPresGrad_dP[m_numPhases][2]{}; + // real64 presGrad = 0.0; + // real64 dPresGrad_dP[2]{0.0, 0.0}; + + real64 gravHead[m_numPhases]{}; + real64 dGravHead_dP[m_numPhases][2]{}; + // real64 gravHead = 0.0; + // real64 dGravHead_dP[2]{0.0, 0.0}; + + real64 capGrad[m_numPhases]{}; + real64 dCapGrad_dP[m_numPhases][2]{}; + real64 dCapGrad_dS[m_numPhases][2]{}; + + real64 fluxVal[m_numPhases]{}; + real64 dFlux_dP[m_numPhases][2]{}; + real64 dFlux_dS[m_numPhases][2]{}; + // real64 fluxVal = 0.0; + // real64 dFlux_dP[2]{0.0, 0.0}; + + real64 mobility[m_numPhases]{}; + real64 dMob_dP[m_numPhases][2]{}; + real64 dMob_dS[m_numPhases][2]{}; + + real64 const trans[2] = { stack.transmissibility[connectionIndex][0], stack.transmissibility[connectionIndex][1] }; + real64 const dTrans_dP[2] = { stack.dTrans_dPres[connectionIndex][0], stack.dTrans_dPres[connectionIndex][1] }; + + // cell indices + localIndex const seri[2] = {m_seri( iconn, k[0] ), m_seri( iconn, k[1] )}; + localIndex const sesri[2] = {m_sesri( iconn, k[0] ), m_sesri( iconn, k[1] )}; + localIndex const sei[2] = {m_sei( iconn, k[0] ), m_sei( iconn, k[1] )}; + + // loop over phases + for( integer ip = 0; ip < m_numPhases; ++ip ) + { + + // calculate quantities on primary connected cells + for( integer ke = 0; ke < 2; ++ke ) + { + // density + real64 const density = m_dens[seri[ke]][sesri[ke]][sei[ke]][ip]; + real64 const dDens_dP = m_dDens_dPres[seri[ke]][sesri[ke]][sei[ke]][ip]; + + // average density and derivatives + densMean[ip] += 0.5 * density; // rho = (rho1 + rho2) / 2 + dDensMean_dP[ip][ke] = 0.5 * dDens_dP; // drho/dP = { (drho1/dP)/2 , (drho2/dP)/2 } + } + + //***** calculation of flux ***** + + // compute potential difference + real64 potScale = 0.0; + real64 dPresGrad_dTrans = 0.0; + real64 dGravHead_dTrans = 0.0; + real64 dCapGrad_dTrans = 0.0; + int signPotDiff[2] = {1, -1}; + + for( integer ke = 0; ke < 2; ++ke ) + { + localIndex const er = seri[ke]; + localIndex const esr = sesri[ke]; + localIndex const ei = sei[ke]; + + real64 const pressure = m_pres[er][esr][ei]; // P = P1 || P2 + presGrad[ip] += trans[ke] * pressure; // DPv = T (P1 - P2) + dPresGrad_dTrans += signPotDiff[ke] * pressure; // dDPv/dT = (P1 - P2) + dPresGrad_dP[ip][ke] = trans[ke]; // dDPv/dP = {T , -T} + + real64 const gravD = trans[ke] * m_gravCoef[er][esr][ei]; // D = T g z1 || -T g z2 + real64 const pot = trans[ke] * pressure - densMean[ip] * gravD; // Phi = T P1 - rho T g z1 || -T P2 + rho T g z2 + + gravHead[ip] += densMean[ip] * gravD; // DPg = rho (T g z1 - T g z2) = T rho g (z1 - z2) + dGravHead_dTrans += signPotDiff[ke] * densMean[ip] * m_gravCoef[er][esr][ei]; // dDPg/dT = rho g z1 - rho g z2 = rho g (z1 - z2) + + for( integer i = 0; i < 2; ++i ) + { + dGravHead_dP[ip][i] += dDensMean_dP[ip][i] * gravD; // dDPg/dP = {drho1/dP * T g (z1 - z2) , drho2/dP * T g (z1 - z2)} + } + + if ( m_hasCapPressure ) // check sign convention + { + real64 const capPres = m_phaseCapPressure[er][esr][ei]; // Pc = Pc1 || Pc2 + dCapGrad_dTrans -= signPotDiff[ke] * capPres; // dDPc/dT = (-Pc1 + Pc2) + pot -= trans[ke] * capPres; // Phi = T P1 - rho T g z1 - T Pc1 || -T P2 + rho T g z2 + T Pc2 + capGrad[ip] -= trans[ke] * capPres; // DPc = T (-Pc1 + Pc2) + } + + potScale = fmax( potScale, fabs( pot ) ); // maxPhi = Phi1 > Phi2 ? Phi1 : Phi2 + } + + for( integer ke = 0; ke < 2; ++ke ) + { + dPresGrad_dP[ip][ke] += dTrans_dP[ke] * dPresGrad_dTrans; // dDPv/dP = { T + dT/dP1 * (P1 - P2) , -T + dT/dP2 * (P1 - P2)} + dGravHead_dP[ip][ke] += dTrans_dP[ke] * dGravHead_dTrans; // dDPg/dP = { drho1/dP * T g (z1 - z2) + dT/dP1 * rho g (z1 - z2) , + // drho2/dP * T g (z1 - z2) + dT/dP2 * rho g (z1 - z2) } + if ( m_hasCapPressure ) + { + dCapGrad_dP[ip][ke] += dTrans_dP[ke] * dCapGrad_dTrans; // dDPc/dP = { dT/dP1 * (-Pc1 + Pc2) , dT/dP2 * (-Pc1 + Pc2) } + } + } + + // *** upwinding *** + + // compute potential gradient + real64 const potGrad = presGrad[ip] - gravHead[ip]; // DPhi = T (P1 - P2) - T rho g (z1 - z2) + if ( m_hasCapPressure ) + { + potGrad += capGrad[ip]; // DPhi = T (P1 - P2) - T rho g (z1 - z2) + T (-Pc1 + Pc2) + } + + // compute upwinding tolerance + real64 constexpr upwRelTol = 1e-8; + real64 const upwAbsTol = fmax( potScale * upwRelTol, LvArray::NumericLimits< real64 >::epsilon ); // abstol = maxPhi * tol > eps ? maxPhi * tol : eps + + // decide mobility coefficients - smooth variation in [-upwAbsTol; upwAbsTol] + real64 const alpha = ( potGrad + upwAbsTol ) / ( 2 * upwAbsTol ); // alpha = (DPhi + abstol) / abstol / 2 + + // choose upstream cell + // real64 mobility{}; + // real64 dMob_dP[2]{}; + if( alpha <= 0.0 || alpha >= 1.0 ) // no smoothing needed + { + localIndex const k_up = 1 - localIndex( fmax( fmin( alpha, 1.0 ), 0.0 ) ); // 1 upwind -> k_up = 0 || 2 upwind -> k_up = 1 + + mobility[ip] = m_mob[seri[k_up]][sesri[k_up]][sei[k_up]][ip]; // M = Mupstream + dMob_dP[ip][k_up] = m_dMob_dPres[seri[k_up]][sesri[k_up]][sei[k_up]][ip]; // dM/dP = {dM/dP1 , 0} OR {0 , dM/dP2} + dMob_dS[ip][k_up] = m_dMob_dSat[seri[k_up]][sesri[k_up]][sei[k_up]][ip]; // dM/dS = {dM/dS1 , 0} OR {0 , dM/dS2} + } + else // perform smoothing + { + real64 const mobWeights[2] = { alpha, 1.0 - alpha }; + for( integer ke = 0; ke < 2; ++ke ) + { + mobility[ip] += mobWeights[ke] * m_mob[seri[ke]][sesri[ke]][sei[ke]][ip]; // M = alpha * M1 + (1 - alpha) * M2 + dMob_dP[ip][ke] = mobWeights[ke] * m_dMob_dPres[seri[ke]][sesri[ke]][sei[ke]][ip]; // dM/dP = {alpha * dM1/dP1 , (1 - alpha) * dM2/dP2} + dMob_dS[ip][ke] = mobWeights[ke] * m_dMob_dSat[seri[ke]][sesri[ke]][sei[ke]][ip]; // dM/dP = {alpha * dM1/dS1 , (1 - alpha) * dM2/dS2} + } + } + + // pressure gradient depends on all points in the stencil + for( integer ke = 0; ke < 2; ++ke ) + { + dFlux_dP[ip][ke] += dPresGrad_dP[ip][ke]; // dF/dP = { T + dT/dP1 * (P1 - P2) , + // -T + dT/dP2 * (P1 - P2) } + } + + // gravitational head depends only on the two cells connected (same as mean density) + for( integer ke = 0; ke < 2; ++ke ) + { + dFlux_dP[ip][ke] -= dGravHead_dP[ip][ke]; // dF/dP = { T + dT/dP1 * (P1 - P2) - drho1/dP * T g (z1 - z2) - dT/dP1 * rho g (z1 - z2) , + // -T + dT/dP2 * (P1 - P2) - drho2/dP * T g (z1 - z2) - dT/dP2 * rho g (z1 - z2) } + } + + // capillary pressure contribution + if ( m_hasCapPressure ) + { + for( integer ke = 0; ke < 2; ++ke ) + { + dFlux_dP[ip][ke] += dCapGrad_dP[ip][ke]; // dF/dP = { T + dT/dP1 * (P1 - P2) - drho1/dP * T g (z1 - z2) - dT/dP1 * rho g (z1 - z2) + dT/dP1 * (-Pc1 + Pc2) , + // -T + dT/dP2 * (P1 - P2) - drho2/dP * T g (z1 - z2) - dT/dP2 * rho g (z1 - z2) + dT/dP2 * (-Pc1 + Pc2) } + } + } + + // compute the flux and derivatives using upstream cell mobility + fluxVal[ip] = mobility[ip] * potGrad; // F = M * DPhi + + for( integer ke = 0; ke < 2; ++ke ) + { + dFlux_dP[ip][ke] *= mobility[ip]; // dF/dP = { M [ T + dT/dP1 * (P1 - P2) - drho1/dP * T g (z1 - z2) - dT/dP1 * rho g (z1 - z2) + dT/dP1 * (-Pc1 + Pc2)] , + // M [-T + dT/dP2 * (P1 - P2) - drho2/dP * T g (z1 - z2) - dT/dP2 * rho g (z1 - z2) + dT/dP2 * (-Pc1 + Pc2)] } + } + + // add contribution from upstream cell mobility derivatives + for( integer ke = 0; ke < 2; ++ke ) + { + dFlux_dP[ip][ke] += dMob_dP[ip][ke] * potGrad; // dF/dP = { M [ T + dT/dP1 * (P1 - P2) - drho1/dP * T g (z1 - z2) - dT/dP1 * rho g (z1 - z2) + dT/dP1 * (-Pc1 + Pc2)] + dM/dP1 * DPhi , + // M [-T + dT/dP2 * (P1 - P2) - drho2/dP * T g (z1 - z2) - dT/dP2 * rho g (z1 - z2) + dT/dP2 * (-Pc1 + Pc2)] + dM/dP2 * DPhi } + + dFlux_dS[ip][ke] += dMob_dS[ip][ke] * potGrad; // dF/dS = { dM/dS1 * DPhi , dM/dS2 * DPhi } + } + + // populate local flux vector and derivatives + stack.localFlux[k[0]*numEqn + ip] += m_dt * fluxVal[ip]; + stack.localFlux[k[1]*numEqn + ip] -= m_dt * fluxVal[ip]; + + for( integer ke = 0; ke < 2; ++ke ) + { + // pressure + localIndex const localDofIndexPres = k[ke] * numDof; + stack.localFluxJacobian[k[0]*numEqn + ip][localDofIndexPres] += m_dt * dFlux_dP[ip][ke]; + stack.localFluxJacobian[k[1]*numEqn + ip][localDofIndexPres] -= m_dt * dFlux_dP[ip][ke]; + + // saturation (hard-coded for 2-phase currently) + localIndex const localDofIndexSat = k[ke] * numDof + 1; + stack.localFluxJacobian[k[0]*numEqn + ip][localDofIndexSat] += m_dt * dFlux_dS[ip][ke]; + stack.localFluxJacobian[k[1]*numEqn + ip][localDofIndexSat] -= m_dt * dFlux_dS[ip][ke]; + } + + // Customize the kernel with this lambda + kernelOp( k, seri, sesri, sei, connectionIndex, alpha, mobility, potGrad, fluxVal, dFlux_dP, dFlux_dS ); // Not sure what this does + + } // loop over phases + + connectionIndex++; + } + } // loop over connection elements + } + + /** + * @brief Performs the complete phase for the kernel. + * @param[in] iconn the connection index + * @param[inout] stack the stack variables + */ + template< typename FUNC = multiPhaseBaseKernels::NoOpFunc > + GEOS_HOST_DEVICE + void complete( localIndex const iconn, + StackVariables & stack, + FUNC && kernelOp = singlePhaseBaseKernels::NoOpFunc{} ) const + { + // add contribution to residual and jacobian into: + // - the mass balance equation + // note that numDof includes derivatives wrt temperature if this class is derived in ThermalKernels + for( integer i = 0; i < stack.numFluxElems; ++i ) + { + if( m_ghostRank[m_seri( iconn, i )][m_sesri( iconn, i )][m_sei( iconn, i )] < 0 ) + { + globalIndex const globalRow = m_dofNumber[m_seri( iconn, i )][m_sesri( iconn, i )][m_sei( iconn, i )]; + localIndex const localRow = LvArray::integerConversion< localIndex >( globalRow - m_rankOffset ); + GEOS_ASSERT_GE( localRow, 0 ); + GEOS_ASSERT_GT( m_localMatrix.numRows(), localRow ); + + RAJA::atomicAdd( parallelDeviceAtomic{}, &m_localRhs[localRow], stack.localFlux[i * numEqn] ); + m_localMatrix.addToRowBinarySearchUnsorted< parallelDeviceAtomic >( localRow, + stack.dofColIndices.data(), + stack.localFluxJacobian[i * numEqn].dataIfContiguous(), // fix numbering + stack.stencilSize * numDof ); + + // call the lambda to assemble additional terms, such as thermal terms + kernelOp( i, localRow ); + } + } + } + + /** + * @brief Performs the kernel launch + * @tparam POLICY the policy used in the RAJA kernels + * @tparam KERNEL_TYPE the kernel type + * @param[in] numConnections the number of connections + * @param[inout] kernelComponent the kernel component providing access to setup/compute/complete functions and stack variables + */ + template< typename POLICY, typename KERNEL_TYPE > + static void + launch( localIndex const numConnections, + KERNEL_TYPE const & kernelComponent ) + { + GEOS_MARK_FUNCTION; + + forAll< POLICY >( numConnections, [=] GEOS_HOST_DEVICE ( localIndex const iconn ) + { + typename KERNEL_TYPE::StackVariables stack( kernelComponent.stencilSize( iconn ), + kernelComponent.numPointsInFlux( iconn ) ); + + kernelComponent.setup( iconn, stack ); + kernelComponent.computeFlux( iconn, stack ); + kernelComponent.complete( iconn, stack ); + } ); + } + +protected: + + // Stencil information + + /// Reference to the stencil wrapper + STENCILWRAPPER const m_stencilWrapper; + + /// Connection to element maps + typename STENCILWRAPPER::IndexContainerViewConstType const m_seri; + typename STENCILWRAPPER::IndexContainerViewConstType const m_sesri; + typename STENCILWRAPPER::IndexContainerViewConstType const m_sei; +}; + + +/****************************************** */ /** * @class FaceBasedAssemblyKernelFactory @@ -209,8 +692,11 @@ class FaceBasedAssemblyKernelFactory */ template< typename POLICY, typename STENCILWRAPPER > static void - createAndLaunch( globalIndex const rankOffset, + createAndLaunch( integer const numPhases, + globalIndex const rankOffset, // add capillary pressure and total mass equation flags string const & dofKey, + integer const hasCapPressure, + integer const useTotalMassEquation, string const & solverName, ElementRegionManager const & elemManager, STENCILWRAPPER const & stencilWrapper, @@ -218,21 +704,22 @@ class FaceBasedAssemblyKernelFactory CRSMatrixView< real64, globalIndex const > const & localMatrix, arrayView1d< real64 > const & localRhs ) { - integer constexpr NUM_EQN = 1; - integer constexpr NUM_DOF = 1; + integer constexpr NUM_EQN = 2; + integer constexpr NUM_DOF = 2; ElementRegionManager::ElementViewAccessor< arrayView1d< globalIndex const > > dofNumberAccessor = elemManager.constructArrayViewAccessor< globalIndex, 1 >( dofKey ); dofNumberAccessor.setName( solverName + "/accessors/" + dofKey ); using kernelType = FaceBasedAssemblyKernel< NUM_EQN, NUM_DOF, STENCILWRAPPER >; - typename kernelType::SinglePhaseFlowAccessors flowAccessors( elemManager, solverName ); - typename kernelType::SinglePhaseFluidAccessors fluidAccessors( elemManager, solverName ); + typename kernelType::ImmiscibleMultiPhaseFlowAccessors flowAccessors( elemManager, solverName ); + typename kernelType::ImmiscibleMultiPhaseFluidAccessors fluidAccessors( elemManager, solverName ); + typename kernelType::CapPressureAccessors capPressureAccessors( elemManager, solverName ); typename kernelType::PermeabilityAccessors permAccessors( elemManager, solverName ); - kernelType kernel( rankOffset, stencilWrapper, dofNumberAccessor, - flowAccessors, fluidAccessors, permAccessors, - dt, localMatrix, localRhs ); + kernelType kernel( numPhases, rankOffset, stencilWrapper, dofNumberAccessor, + flowAccessors, fluidAccessors, capPressureAccessors, permAccessors, + dt, localMatrix, localRhs, hasCapPressure, useTotalMassEquation ); kernelType::template launch< POLICY >( stencilWrapper.size(), kernel ); } }; @@ -243,4 +730,6 @@ class FaceBasedAssemblyKernelFactory } // namesace immiscible multiphasekernels -} // namespace geos \ No newline at end of file +} // namespace geos + +#endif //GEOS_PHYSICSSOLVERS_FLUIDFLOW_MULTIPHASEKERNELS_HPP \ No newline at end of file From 1b190a89a9da28bffc84249c16b740d7da1f0ac5 Mon Sep 17 00:00:00 2001 From: rpiazza87 Date: Mon, 12 Aug 2024 14:40:59 -0700 Subject: [PATCH 013/102] x --- .../fluidFlow/ImmiscibleMultiphaseKernels.hpp | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseKernels.hpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseKernels.hpp index c6f1a05c868..ec0adf08319 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseKernels.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseKernels.hpp @@ -360,7 +360,7 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase * @param[inout] stack the stack variables * @param[in] NoOpFunc the function used to customize the computation of the flux */ - template< typename FUNC = multiPhaseBaseKernels::NoOpFunc > + template< typename FUNC = singlePhaseBaseKernels::NoOpFunc > // should change to multiphase GEOS_HOST_DEVICE void computeFlux( localIndex const iconn, StackVariables & stack, @@ -599,7 +599,7 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase * @param[in] iconn the connection index * @param[inout] stack the stack variables */ - template< typename FUNC = multiPhaseBaseKernels::NoOpFunc > + template< typename FUNC = singlePhaseBaseKernels::NoOpFunc > // should change to multiphase GEOS_HOST_DEVICE void complete( localIndex const iconn, StackVariables & stack, @@ -615,13 +615,18 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase globalIndex const globalRow = m_dofNumber[m_seri( iconn, i )][m_sesri( iconn, i )][m_sei( iconn, i )]; localIndex const localRow = LvArray::integerConversion< localIndex >( globalRow - m_rankOffset ); GEOS_ASSERT_GE( localRow, 0 ); - GEOS_ASSERT_GT( m_localMatrix.numRows(), localRow ); - - RAJA::atomicAdd( parallelDeviceAtomic{}, &m_localRhs[localRow], stack.localFlux[i * numEqn] ); - m_localMatrix.addToRowBinarySearchUnsorted< parallelDeviceAtomic >( localRow, - stack.dofColIndices.data(), - stack.localFluxJacobian[i * numEqn].dataIfContiguous(), // fix numbering - stack.stencilSize * numDof ); + GEOS_ASSERT_GT( m_localMatrix.numRows(), localRow + numEqn); + + for( integer ic = 0; ic < numEqn; ++ic ) + { + RAJA::atomicAdd( parallelDeviceAtomic{}, &m_localRhs[localRow + ic], + stack.localFlux[i * numEqn + ic] ); + m_localMatrix.addToRowBinarySearchUnsorted< parallelDeviceAtomic > + ( localRow + ic, + stack.dofColIndices.data(), + stack.localFluxJacobian[i * numEqn + ic].dataIfContiguous(), + stack.stencilSize * numDof ); + } // call the lambda to assemble additional terms, such as thermal terms kernelOp( i, localRow ); From 33c6c0f0abfc2e1e95326f564c189eaf8cfdc852 Mon Sep 17 00:00:00 2001 From: rpiazza87 Date: Mon, 12 Aug 2024 14:53:06 -0700 Subject: [PATCH 014/102] x --- .../fluidFlow/ImmiscibleMultiphaseFlow.cpp | 31 +++---------------- .../fluidFlow/ImmiscibleMultiphaseFlow.hpp | 3 ++ 2 files changed, 7 insertions(+), 27 deletions(-) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp index 507ab656c42..d0a6f3d80af 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp @@ -626,8 +626,11 @@ void ImmiscibleMultiphaseFlow::assembleFluxTerms( real64 const dt, { fluxApprox.forAllStencils( mesh, [&]( auto & stencil ) { - FaceBasedAssemblyKernelFactory::createAndLaunch< parallelDevicePolicy<> >( dofManager.rankOffset(), + FaceBasedAssemblyKernelFactory::createAndLaunch< parallelDevicePolicy<> >( m_numPhases, + dofManager.rankOffset(), dofKey, + m_hasCapPressure, + m_useTotalMassEquation, getName(), mesh.getElemManager(), stencilWrapper, @@ -639,32 +642,6 @@ void ImmiscibleMultiphaseFlow::assembleFluxTerms( real64 const dt, } -void ImmiscibleMultiphaseFlow::setupDofs( DomainPartition const & domain, - DofManager & dofManager ) const -{ - GEOS_UNUSED_VAR(domain, dofManager); - //// add a field for the cell-centered degrees of freedom - //dofManager.addField( viewKeyStruct::elemDofFieldString(), - // FieldLocation::Elem, - // m_numDofPerCell, - // getMeshTargets() ); - - //// this call with instruct GEOS to reorder the dof numbers - //dofManager.setLocalReorderingType( viewKeyStruct::elemDofFieldString(), - // DofManager::LocalReorderingType::ReverseCutHillMcKee ); - - //// for the volume balance equation, disable global coupling - //// this equation is purely local (not coupled to neighbors or other physics) - //dofManager.disableGlobalCouplingForEquation( viewKeyStruct::elemDofFieldString(), - // m_numComponents ); - - - //NumericalMethodsManager const & numericalMethodManager = domain.getNumericalMethodManager(); - //FiniteVolumeManager const & fvManager = numericalMethodManager.getFiniteVolumeManager(); - //FluxApproximationBase const & fluxApprox = fvManager.getFluxApproximation( m_discretizationName ); - //dofManager.addCoupling( viewKeyStruct::elemDofFieldString(), fluxApprox ); -} - // Ryan: Looks like this will need to be overwritten as well... // I have left the CompositionalMultiphaseFVM implementation for reference void ImmiscibleMultiphaseFlow::setupDofs( DomainPartition const & domain, diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp index 34d603abadb..fec9c186808 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp @@ -239,6 +239,9 @@ class ImmiscibleMultiphaseFlow : public FlowSolverBase /// flag to determine whether or not to apply capillary pressure integer m_hasCapPressure; + /// flag to determine whether or not to use total mass formulation + integer m_useTotalMassEquation; + struct viewKeyStruct : public FlowSolverBase::viewKeyStruct { static constexpr char const * capPressureNamesString() { return "capPressureNames"; } From cc35e5972463152f7d319258dda879cf038c30cb Mon Sep 17 00:00:00 2001 From: Ammara-14 Date: Fri, 2 Aug 2024 12:06:38 -0700 Subject: [PATCH 015/102] add temperature to input file --- src/coreComponents/LvArray | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreComponents/LvArray b/src/coreComponents/LvArray index e7bf1096d57..ec26694afbc 160000 --- a/src/coreComponents/LvArray +++ b/src/coreComponents/LvArray @@ -1 +1 @@ -Subproject commit e7bf1096d57558be720f177141c40e4ab69b3f5e +Subproject commit ec26694afbcdd137533b6f04ce8f8c264ff8c1fb From 297669c30095604ef48899376c9be107a46765b1 Mon Sep 17 00:00:00 2001 From: Ammara-14 Date: Thu, 8 Aug 2024 15:59:21 -0700 Subject: [PATCH 016/102] Initial implementation of assembleAccumulationTerm --- .../fluidFlow/ImmiscibleMultiphaseFlow.cpp | 199 +++++++++++------- .../ImmiscibleMultiphaseFlowFields.hpp | 11 +- 2 files changed, 128 insertions(+), 82 deletions(-) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp index d0a6f3d80af..db70db94679 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp @@ -48,82 +48,23 @@ using namespace dataRepository; using namespace constitutive; using namespace fields::immiscibleMultiphaseFlow; -// Fluid model for isothermal T = 175 oC -real64 co2_viscosity(real64 P) -{ - P = P / 1000000.0; // check whether GEOS uses Pa or MPa - return ( -1.5596 * pow(10, -10) * pow(P, 3) + 1.94571 * pow(10, -8) * pow(P, 2) + 6.77304 * pow(10, -8) * P + 0.0000214166); // [Pa.s] -} - -real64 co2_dviscosity(real64 P) -{ - P = P / 1000000.0; // check whether GEOS uses Pa or MPa - return ( -4.6788 * pow(10, -10) * pow(P, 2) + 3.89142 * pow(10, -8) * P + 6.77304 * pow(10, -8)); // [Pa.s/MPa] -} - -real64 co2_density(real64 P) -{ - P = P / 1000000.0; // check whether GEOS uses Pa or MPa - return ( -0.0000126691 * pow(P, 3) - 0.118131 * pow(P, 2) + 19.6211 * P - 52.0635 ); // [kg/m3] -} - -real64 co2_ddensity(real64 P) -{ - P = P / 1000000.0; // check whether GEOS uses Pa or MPa - return ( -0.0000380073 * pow(P, 2) - 0.236262 * P + 19.6211 ); // [kg/m3.MPa] -} - -real64 water_viscosity(real64 P) -{ - return ( 0.000164 ); // [Pa.s] -} - -real64 water_dviscosity(real64 P) -{ - return ( 0.0 ); // [Pa.s/MPa] -} - -real64 water_density(real64 P) -{ - P = P / 1000000.0; // check whether GEOS uses Pa or MPa - return ( 0.55125 * P + 893.06044); // [kg/m3] +real64 computeDensityL ( real64 P ) { + return (1.0e-6 * (P * P)); } -real64 water_ddensity(real64 P) -{ - return ( 0.55125 ); // [kg/m3.MPa] +real64 computedDensitydPL ( real64 P ) { + return (1.0e-6 * 2.0 * (P)); } -// Rock-Fluid model -real64 co2_relperm(real64 S) -{ - return ( pow(1 - S, 2) ); // [-] -} - -real64 co2_drelperm(real64 S) -{ - return ( 2.0 * (1 - S) ); // [-] +real64 computeDensityV ( real64 P ) { + return (1.0e-8 * (P * P)); } -real64 water_relperm(real64 S) -{ - return ( pow(S, 6) ); // [-] -} - -real64 water_drelperm(real64 S) -{ - return ( 6.0 * pow(S, 5) ); // [-] +real64 computedDensitydPV ( real64 P ) { + return (1.0e-8 * 2.0 * (P)); } -real64 co2_cappress(real64 S) -{ - return ( 0.00049309 * pow(S, -2.34806) ); // [MPa] check whether GEOS uses Pa or MPa -} -real64 co2_dcappress(real64 S) -{ - return ( -0.00021 * pow(S, -1.34806) ); // [MPa] check whether GEOS uses Pa or MPa -} ImmiscibleMultiphaseFlow::ImmiscibleMultiphaseFlow( const string & name, Group * const parent ) @@ -580,6 +521,9 @@ void ImmiscibleMultiphaseFlow::assembleSystem( real64 const GEOS_UNUSED_PARAM( t localRhs ); } + +// The assembleAccumulationTerm below is Added by Ammar. + void ImmiscibleMultiphaseFlow::assembleAccumulationTerm( DomainPartition & domain, DofManager const & dofManager, CRSMatrixView< real64, globalIndex const > const & localMatrix, @@ -587,21 +531,114 @@ void ImmiscibleMultiphaseFlow::assembleAccumulationTerm( DomainPartition & domai { GEOS_MARK_FUNCTION; + // I need to pass this: ObjectManagerBase & dataGroup + // GEOS_UNUSED_VAR( domain, dofManager, localMatrix, localRhs ); + + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, + MeshLevel const & mesh, + arrayView1d< string const > const & regionNames ) + { + mesh.getElemManager().forElementSubRegions( regionNames, + [&]( localIndex const, + ElementSubRegionBase const & subRegion ) + { + string const dofKey = dofManager.getKey( viewKeyStruct::elemDofFieldString() ); + string const & solidName = subRegion.getReference< string >( viewKeyStruct::solidNamesString() ); + + // MultiFluidBase const & fluid = getConstitutiveModel< MultiFluidBase >( subRegion, fluidName ); + CoupledSolidBase const & solid = getConstitutiveModel< CoupledSolidBase >( subRegion, solidName ); + + //arrayView1d< real64 const > const pres = dataGroup.getField< fields::flow::pressure >(); + integer const m_numofPhases = 2; + globalIndex const m_rankOffset = dofManager.rankOffset(); + arrayView1d< globalIndex const > const m_dofNumber = subRegion.getReference< array1d< globalIndex > >( dofKey ); + arrayView1d< integer const > const m_elemGhostRank= subRegion.ghostRank(); + arrayView1d< real64 const > const m_volume = subRegion.getElementVolume(); + arrayView2d< real64 const > const m_porosity = solid.getPorosity(); + arrayView2d< real64 const > const m_dPoro_dPres = solid.getDporosity_dPressure(); + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const m_phaseVolFrac= subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); + arrayView3d< real64 const, immiscibleFlow::USD_PHASE_DS > const m_dPhaseVolFrac = subRegion.template getField< fields::immiscibleMultiphaseFlow::dPhaseVolumeFraction >(); + //arrayView3d< real64 const, immiscibleFlow::USD_PHASE > m_phaseDens = fluid.phaseDensity(); + //arrayView4d< real64 const, immiscibleFlow::USD_PHASE_DS > m_dPhaseDens = fluid.dPhaseDensity(); + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const m_phaseMass_n = subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseMass_n >(); + CRSMatrixView< real64, globalIndex const > m_localMatrix_2 = localMatrix; + arrayView1d< real64 > m_localRhs = localRhs; + //BitFlags< ElementBasedAssemblyKernelFlags > m_kernelFlags = kernelFlags; + GEOS_MARK_FUNCTION; + + integer const numElems = subRegion.size(); + forAll< parallelDevicePolicy<> >( numElems, [=] GEOS_HOST_DEVICE ( localIndex const ei ) + { + if( m_elemGhostRank( ei ) >= 0 ) + { + return; + } + + // setup + globalIndex dofIndices[2]{}; + real64 localResidual[2]{}; + real64 localJacobian[2][2]{}; + + real64 const poreVolume = m_volume[ei] * m_porosity[ei][0]; + real64 const dPoreVolume_dPres = m_volume[ei] * m_dPoro_dPres[ei][0]; + + localIndex localRow = m_dofNumber[ei] - m_rankOffset; + + for( integer idof = 0; idof < m_numDofPerCell; ++idof ) + { + dofIndices[idof] = m_dofNumber[ei] + idof; + } + + // compute accumulation + + + for( integer ip = 0; ip < m_numofPhases; ++ip ) + { + + real64 const dummyPressure = 1.0e6; + + real64 m_phaseDens = computeDensityV ( dummyPressure ); + real64 dPhaseDens = computedDensitydPV ( dummyPressure ); + + if( ip == 1) + { + m_phaseDens = computeDensityL ( dummyPressure ); + dPhaseDens = computedDensitydPL ( dummyPressure ); + } + + real64 const phaseMass = poreVolume * m_phaseVolFrac[ei][ip] * m_phaseDens; + real64 const phaseMass_n = m_phaseMass_n[ei][ip]; + + localResidual[ip] += phaseMass - phaseMass_n; + + real64 const dPhaseMass_dP = dPoreVolume_dPres * m_phaseVolFrac[ei][ip] * m_phaseDens + + poreVolume * m_phaseVolFrac[ei][ip] * dPhaseDens; + localJacobian[ip][0] += dPhaseMass_dP; + + real64 const dPhaseMass_dS = poreVolume * m_phaseDens; + // Ammar:- not quite clear on how to fill jacobian for dRdS?? + localJacobian[ip][ip + 1] += dPhaseMass_dS; + } + + // complete + + integer const numRows = m_numofPhases + 1; + + for( integer i = 0; i < numRows; ++i ) + { + m_localRhs[localRow + i] += localResidual[i]; + m_localMatrix_2.addToRow< serialAtomic >( localRow + i, + dofIndices, + localJacobian[i], + m_numDofPerCell ); + } + + } ); + + } ); + } ); + - GEOS_UNUSED_VAR( domain, dofManager, localMatrix, localRhs ); - - // forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, - // MeshLevel const & mesh, - // arrayView1d< string const > const & regionNames ) - // { - // mesh.getElemManager().forElementSubRegions( regionNames, - // [&]( localIndex const, - // ElementSubRegionBase const & subRegion ) - // { - // string const dofKey = dofManager.getKey( viewKeyStruct::elemDofFieldString() ); - // string const & solidName = subRegion.getReference< string >( viewKeyStruct::solidNamesString() ); - // } ); - // } ); } void ImmiscibleMultiphaseFlow::assembleFluxTerms( real64 const dt, diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlowFields.hpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlowFields.hpp index 3cb4fc7a6df..796b2f347e0 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlowFields.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlowFields.hpp @@ -77,13 +77,22 @@ DECLARE_FIELD( phaseMobility, WRITE_AND_READ, "Phase mobility" ); +DECLARE_FIELD( dPhaseVolumeFraction, + "dPhaseVolumeFraction", + array3dLayoutPhase_dS, + 0, + NOPLOT, + NO_WRITE, + "Derivative of phase volume fraction with respect to pressure, temperature, global component density" ); + DECLARE_FIELD( dPhaseMobility, "dPhaseMobility", array3dLayoutPhase_dS, 0, NOPLOT, NO_WRITE, - "Derivative of phase volume fraction with respect to pressure, temperature, global component density" ); + "Derivative of phase mobility with respect to pressure, temperature, global component density" ); + DECLARE_FIELD( phaseOutflux, "phaseOutflux", From dc73aa27805f605803f7fc99727688a4d8bc23ce Mon Sep 17 00:00:00 2001 From: Ammara-14 Date: Tue, 13 Aug 2024 18:49:51 -0700 Subject: [PATCH 017/102] Few fixes in the accumulation term assumbly and added fields for the phase properties reflecting the comments from the meeting on Aug-13-2024 --- .../fluidFlow/ImmiscibleMultiphaseFlow.cpp | 89 ++++++++++--------- .../ImmiscibleMultiphaseFlowFields.hpp | 39 +++++++- 2 files changed, 84 insertions(+), 44 deletions(-) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp index db70db94679..e3766d9ea03 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp @@ -522,7 +522,7 @@ void ImmiscibleMultiphaseFlow::assembleSystem( real64 const GEOS_UNUSED_PARAM( t } -// The assembleAccumulationTerm below is Added by Ammar. +// This part of the code "assembleAccumulationTerm" is added by Ammar along with the comments. void ImmiscibleMultiphaseFlow::assembleAccumulationTerm( DomainPartition & domain, DofManager const & dofManager, @@ -531,8 +531,6 @@ void ImmiscibleMultiphaseFlow::assembleAccumulationTerm( DomainPartition & domai { GEOS_MARK_FUNCTION; - // I need to pass this: ObjectManagerBase & dataGroup - // GEOS_UNUSED_VAR( domain, dofManager, localMatrix, localRhs ); forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, MeshLevel const & mesh, @@ -545,31 +543,35 @@ void ImmiscibleMultiphaseFlow::assembleAccumulationTerm( DomainPartition & domai string const dofKey = dofManager.getKey( viewKeyStruct::elemDofFieldString() ); string const & solidName = subRegion.getReference< string >( viewKeyStruct::solidNamesString() ); + // The line below needs to be used once we have a fluid model // MultiFluidBase const & fluid = getConstitutiveModel< MultiFluidBase >( subRegion, fluidName ); CoupledSolidBase const & solid = getConstitutiveModel< CoupledSolidBase >( subRegion, solidName ); - //arrayView1d< real64 const > const pres = dataGroup.getField< fields::flow::pressure >(); - integer const m_numofPhases = 2; - globalIndex const m_rankOffset = dofManager.rankOffset(); - arrayView1d< globalIndex const > const m_dofNumber = subRegion.getReference< array1d< globalIndex > >( dofKey ); - arrayView1d< integer const > const m_elemGhostRank= subRegion.ghostRank(); - arrayView1d< real64 const > const m_volume = subRegion.getElementVolume(); - arrayView2d< real64 const > const m_porosity = solid.getPorosity(); - arrayView2d< real64 const > const m_dPoro_dPres = solid.getDporosity_dPressure(); - arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const m_phaseVolFrac= subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); - arrayView3d< real64 const, immiscibleFlow::USD_PHASE_DS > const m_dPhaseVolFrac = subRegion.template getField< fields::immiscibleMultiphaseFlow::dPhaseVolumeFraction >(); + arrayView1d< real64 const > const pres = subRegion.getField< fields::flow::pressure >(); + integer const numofPhases = 2; + globalIndex const rankOffset = dofManager.rankOffset(); + arrayView1d< globalIndex const > const dofNumber = subRegion.getReference< array1d< globalIndex > >( dofKey ); + arrayView1d< integer const > const elemGhostRank= subRegion.ghostRank(); + arrayView1d< real64 const > const volume = subRegion.getElementVolume(); + arrayView2d< real64 const > const porosity = solid.getPorosity(); + arrayView2d< real64 const > const dPoro_dPres = solid.getDporosity_dPressure(); + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFrac= subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); + // The two lines below need to be used once we have a fluid model //arrayView3d< real64 const, immiscibleFlow::USD_PHASE > m_phaseDens = fluid.phaseDensity(); //arrayView4d< real64 const, immiscibleFlow::USD_PHASE_DS > m_dPhaseDens = fluid.dPhaseDensity(); - arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const m_phaseMass_n = subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseMass_n >(); - CRSMatrixView< real64, globalIndex const > m_localMatrix_2 = localMatrix; - arrayView1d< real64 > m_localRhs = localRhs; + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > phaseDens = subRegion.getField< fields::immiscibleMultiphaseFlow::phaseDensity>(); + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > dPhaseDens = subRegion.getField< fields::immiscibleMultiphaseFlow::dPhaseDensity>(); + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const PhaseMass_n = subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseMass_n >(); + + // The line below is to be used if we want to use the total mass flux formulation //BitFlags< ElementBasedAssemblyKernelFlags > m_kernelFlags = kernelFlags; GEOS_MARK_FUNCTION; integer const numElems = subRegion.size(); - forAll< parallelDevicePolicy<> >( numElems, [=] GEOS_HOST_DEVICE ( localIndex const ei ) + forAll< parallelDevicePolicy<> >( + numElems, [=] GEOS_HOST_DEVICE ( localIndex const ei ) { - if( m_elemGhostRank( ei ) >= 0 ) + if( elemGhostRank( ei ) >= 0 ) { return; } @@ -579,58 +581,59 @@ void ImmiscibleMultiphaseFlow::assembleAccumulationTerm( DomainPartition & domai real64 localResidual[2]{}; real64 localJacobian[2][2]{}; - real64 const poreVolume = m_volume[ei] * m_porosity[ei][0]; - real64 const dPoreVolume_dPres = m_volume[ei] * m_dPoro_dPres[ei][0]; + real64 const poreVolume = volume[ei] * porosity[ei][0]; + real64 const dPoreVolume_dPres = volume[ei] * dPoro_dPres[ei][0]; - localIndex localRow = m_dofNumber[ei] - m_rankOffset; + localIndex localRow = dofNumber[ei] - rankOffset; - for( integer idof = 0; idof < m_numDofPerCell; ++idof ) + for( integer idof = 0; idof < 2; ++idof ) { - dofIndices[idof] = m_dofNumber[ei] + idof; + dofIndices[idof] = dofNumber[ei] + idof; } // compute accumulation - for( integer ip = 0; ip < m_numofPhases; ++ip ) + for( integer ip = 0; ip < numofPhases; ++ip ) { - real64 const dummyPressure = 1.0e6; + // The few lines of code below are to be used if we want to use free functions for the phase density (to test the derivatives) + // real64 const pressure = pres[ei]; - real64 m_phaseDens = computeDensityV ( dummyPressure ); - real64 dPhaseDens = computedDensitydPV ( dummyPressure ); + // real64 phaseDens = computeDensityV ( pressure ); + // real64 dPhaseDens = computedDensitydPV ( pressure ); - if( ip == 1) - { - m_phaseDens = computeDensityL ( dummyPressure ); - dPhaseDens = computedDensitydPL ( dummyPressure ); - } + // if( ip == 1) + // { + // phaseDens = computeDensityL ( pressure ); + // dPhaseDens = computedDensitydPL ( pressure ); + //} - real64 const phaseMass = poreVolume * m_phaseVolFrac[ei][ip] * m_phaseDens; - real64 const phaseMass_n = m_phaseMass_n[ei][ip]; + real64 const phaseMass = poreVolume * phaseVolFrac[ei][ip] * phaseDens[ei][ip]; + real64 const phaseMass_n = PhaseMass_n[ei][ip]; localResidual[ip] += phaseMass - phaseMass_n; - real64 const dPhaseMass_dP = dPoreVolume_dPres * m_phaseVolFrac[ei][ip] * m_phaseDens - + poreVolume * m_phaseVolFrac[ei][ip] * dPhaseDens; + real64 const dPhaseMass_dP = dPoreVolume_dPres * phaseVolFrac[ei][ip] * phaseDens[ei][ip] + + poreVolume * phaseVolFrac[ei][ip] * dPhaseDens[ei][ip]; localJacobian[ip][0] += dPhaseMass_dP; - real64 const dPhaseMass_dS = poreVolume * m_phaseDens; - // Ammar:- not quite clear on how to fill jacobian for dRdS?? - localJacobian[ip][ip + 1] += dPhaseMass_dS; + real64 const dPhaseMass_dS = poreVolume * phaseDens[ei][ip]; + + localJacobian[ip][1] += dPhaseMass_dS; } // complete - integer const numRows = m_numofPhases + 1; + integer const numRows = numofPhases + 1; for( integer i = 0; i < numRows; ++i ) { - m_localRhs[localRow + i] += localResidual[i]; - m_localMatrix_2.addToRow< serialAtomic >( localRow + i, + localRhs[localRow + i] += localResidual[i]; + localMatrix.addToRow< serialAtomic >( localRow + i, dofIndices, localJacobian[i], - m_numDofPerCell ); + 2); } } ); diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlowFields.hpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlowFields.hpp index 796b2f347e0..dcf303e6eca 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlowFields.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlowFields.hpp @@ -109,10 +109,47 @@ DECLARE_FIELD( phaseCFLNumber, LEVEL_0, NO_WRITE, "Phase CFL number" ); -} +DECLARE_FIELD( phaseDensity, + "phaseDensity", + array2dLayoutPhase, + 1000.0, + NOPLOT, + WRITE_AND_READ, + "Phase density" ); + + +DECLARE_FIELD( dPhaseDensity, + "dPhaseDensity", + array2dLayoutPhase, + 0.0, + NOPLOT, + WRITE_AND_READ, + "Phase density derivative with respect to P" ); + +DECLARE_FIELD( phaseViscosity, + "phaseViscosity", + array2dLayoutPhase, + 1.0e-4, + NOPLOT, + WRITE_AND_READ, + "Phase density" ); + + +DECLARE_FIELD( dPhaseViscosity, + "dPhaseViscosity", + array2dLayoutPhase, + 0.0, + NOPLOT, + WRITE_AND_READ, + "Phase density derivative with respect to P" ); + + +} } } + + #endif // GEOS_PHYSICSSOLVERS_FLUIDFLOW_IMMISCIBLEMULTIPHASEFLOWFIELDS_HPP_ From f6d14dc0ea2152eb5c66940dee8d270b4ffadf51 Mon Sep 17 00:00:00 2001 From: rpiazza87 Date: Mon, 19 Aug 2024 16:13:52 -0700 Subject: [PATCH 018/102] update datalayout --- src/coreComponents/common/DataLayouts.hpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/coreComponents/common/DataLayouts.hpp b/src/coreComponents/common/DataLayouts.hpp index d1c892754ee..40b64ada6df 100644 --- a/src/coreComponents/common/DataLayouts.hpp +++ b/src/coreComponents/common/DataLayouts.hpp @@ -232,6 +232,15 @@ static constexpr int USD_PHASE = LvArray::typeManipulation::getStrideOneDimensio /// Phase property compositional derivative unit stride dimension static constexpr int USD_PHASE_DS = LvArray::typeManipulation::getStrideOneDimension( LAYOUT_PHASE_DS{} ); +/// indices of pressure and saturation derivatives +struct DerivativeOffset +{ + /// index of derivative wrt pressure + static integer constexpr dP = 0; + /// index of first derivative wrt compositions + static integer constexpr dS = 1; +}; + } // namespace immiscibleFlow namespace compflow From 477d87e35caa2f380010a2ea73de0b0d53a840d2 Mon Sep 17 00:00:00 2001 From: rpiazza87 Date: Mon, 19 Aug 2024 16:23:35 -0700 Subject: [PATCH 019/102] updated solver files --- .../physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp | 5 +---- .../physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp index e3766d9ea03..a5a5c3491a2 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp @@ -22,8 +22,6 @@ #include "FlowSolverBaseFields.hpp" #include "physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlowFields.hpp" #include "physicsSolvers/fluidFlow/ImmiscibleMultiphaseKernels.hpp" -#include "physicsSolvers/fluidFlow/IsothermalCompositionalMultiphaseBaseKernels.hpp" -#include "physicsSolvers/fluidFlow/IsothermalCompositionalMultiphaseFVMKernels.hpp" #include "constitutive/ConstitutiveManager.hpp" #include "constitutive/capillaryPressure/CapillaryPressureFields.hpp" @@ -678,8 +676,7 @@ void ImmiscibleMultiphaseFlow::assembleFluxTerms( real64 const dt, localMatrix.toViewConstSizes(), localRhs.toView() ); } ); - } ); - + } ); } // Ryan: Looks like this will need to be overwritten as well... diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp index fec9c186808..7cf3a8c1b17 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp @@ -239,7 +239,7 @@ class ImmiscibleMultiphaseFlow : public FlowSolverBase /// flag to determine whether or not to apply capillary pressure integer m_hasCapPressure; - /// flag to determine whether or not to use total mass formulation + /// flag to determine whether or not to use total velocity formulation integer m_useTotalMassEquation; struct viewKeyStruct : public FlowSolverBase::viewKeyStruct From 05261648ade90fc46a75a0eaebe4eb340002c032 Mon Sep 17 00:00:00 2001 From: rpiazza87 Date: Mon, 19 Aug 2024 16:29:08 -0700 Subject: [PATCH 020/102] update kernel --- .../fluidFlow/ImmiscibleMultiphaseKernels.hpp | 136 ++++++++---------- 1 file changed, 60 insertions(+), 76 deletions(-) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseKernels.hpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseKernels.hpp index ec0adf08319..310f7e34c07 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseKernels.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseKernels.hpp @@ -24,17 +24,19 @@ #include "common/GEOS_RAJA_Interface.hpp" #include "constitutive/fluid/singlefluid/SingleFluidBase.hpp" // get correct fluid model #include "constitutive/fluid/singlefluid/SingleFluidFields.hpp" -#include "constitutive/fluid/singlefluid/SlurryFluidBase.hpp" -#include "constitutive/fluid/singlefluid/SlurryFluidFields.hpp" +#include "constitutive/capillaryPressure/CapillaryPressureFields.hpp" +#include "constitutive/capillaryPressure/CapillaryPressureBase.hpp" #include "constitutive/permeability/PermeabilityBase.hpp" #include "constitutive/permeability/PermeabilityFields.hpp" +#include "constitutive/relativePermeability/RelativePermeabilityBase.hpp" +#include "constitutive/relativePermeability/RelativePermeabilityFields.hpp" #include "fieldSpecification/AquiferBoundaryCondition.hpp" #include "finiteVolume/BoundaryStencil.hpp" #include "finiteVolume/FluxApproximationBase.hpp" #include "linearAlgebra/interfaces/InterfaceTypes.hpp" #include "physicsSolvers/fluidFlow/FlowSolverBaseFields.hpp" #include "physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlowFields.hpp" -#include "physicsSolvers/fluidFlow/SinglePhaseBaseKernels.hpp" // create for multiphase for kernels +#include "physicsSolvers/fluidFlow/SinglePhaseBaseKernels.hpp" // check need of multiphase equivalent #include "physicsSolvers/fluidFlow/StencilAccessors.hpp" namespace geos @@ -69,17 +71,11 @@ class FaceBasedAssemblyKernelBase using ImmiscibleMultiphaseFlowAccessors = StencilAccessors< fields::ghostRank, fields::flow::pressure, - fields::flow::pressure_n, - fields::flow::phaseVolumeFraction, - fields::flow::phaseVolumeFraction_n, fields::flow::gravityCoefficient, - fields::flow::phaseMobility, - fields::flow::dPhaseMobility >; // TODO: fix derivatives of mobility - - using ImmiscibleMultiphaseFluidAccessors = - StencilMaterialAccessors< MultiFluidBase, - fields::multifluid::phaseDensity, - fields::multifluid::dPhaseDensity >; + fields::immiscibleMultiphaseFlow::phaseDensity, + fields::immiscibleMultiphaseFlow::dPhaseDensity, + fields::immiscibleMultiphaseFlow::phaseMobility, + fields::immiscibleMultiphaseFlow::dPhaseMobility >; using CapPressureAccessors = StencilMaterialAccessors< CapillaryPressureBase, @@ -89,7 +85,9 @@ class FaceBasedAssemblyKernelBase using PermeabilityAccessors = StencilMaterialAccessors< PermeabilityBase, fields::permeability::permeability, - fields::permeability::dPerm_dPressure >; + fields::permeability::dPerm_dPressure >; + + using Deriv = immiscibleFlow::DerivativeOffset; /** * @brief Constructor for the kernel interface @@ -97,7 +95,6 @@ class FaceBasedAssemblyKernelBase * @param[in] rankOffset the offset of my MPI rank * @param[in] dofNumberAccessor accessor for the dof numbers * @param[in] multiPhaseFlowAccessors accessor for wrappers registered by the solver - * @param[in] multiPhaseFluidAccessors accessor for wrappers registered by the multiphase fluid model * @param[in] capPressureAccessors accessor for wrappers registered by the capillary pressure model * @param[in] permeabilityAccessors accessor for wrappers registered by the permeability model * @param[in] dt time step size @@ -107,8 +104,7 @@ class FaceBasedAssemblyKernelBase FaceBasedAssemblyKernelBase( integer const numPhases, globalIndex const rankOffset, DofNumberAccessor const & dofNumberAccessor, - ImmiscibleMultiphaseFlowAccessors const & multiPhaseFlowAccessors, - ImmiscibleMultiphaseFluidAccessors const & multiPhaseFluidAccessors, + ImmiscibleMultiphaseFlowAccessors const & multiPhaseFlowAccessors, CapPressureAccessors const & capPressureAccessors, PermeabilityAccessors const & permeabilityAccessors, real64 const & dt, @@ -125,11 +121,10 @@ class FaceBasedAssemblyKernelBase m_ghostRank( multiPhaseFlowAccessors.get( fields::ghostRank {} ) ), m_gravCoef( multiPhaseFlowAccessors.get( fields::flow::gravityCoefficient {} ) ), m_pres( multiPhaseFlowAccessors.get( fields::flow::pressure {} ) ), - m_mob( multiPhaseFlowAccessors.get( fields::flow::phaseMobility {} ) ), - m_dMob_dPres( multiPhaseFlowAccessors.get( fields::flow::dPhaseMobility {} ) ), - m_dMob_dSat( multiPhaseFlowAccessors.get( fields::flow::dPhaseMobility {} ) ), - m_dens( multiPhaseFluidAccessors.get( fields::multifluid::phaseDensity {} ) ), - m_dDens_dPres( multiPhaseFluidAccessors.get( fields::multifluid::dPhaseDensity {} ) ), + m_mob( multiPhaseFlowAccessors.get( fields::immiscibleMultiphaseFlow::phaseMobility {} ) ), + m_dMob( multiPhaseFlowAccessors.get( fields::immiscibleMultiphaseFlow::dPhaseMobility {} ) ), + m_dens( multiPhaseFlowAccessors.get( fields::immiscibleMultiphaseFlow::phaseDensity {} ) ), + m_dDens_dPres( multiPhaseFlowAccessors.get( fields::immiscibleMultiphaseFlow::dPhaseDensity {} ) ), m_phaseCapPressure( capPressureAccessors.get( fields::cappres::phaseCapPressure {} ) ), m_dPhaseCapPressure_dPhaseVolFrac( capPressureAccessors.get( fields::cappres::dPhaseCapPressure_dPhaseVolFraction {} ) ), m_localMatrix( localMatrix ), @@ -163,21 +158,18 @@ class FaceBasedAssemblyKernelBase // Primary and secondary variables /// Views on pressure ElementViewConst< arrayView1d< real64 const > > const m_pres; - /// Views on saturation - ElementViewConst< arrayView1d< real64 const > > const m_phaseVolFraction; /// Views on fluid mobility - ElementViewConst< arrayView2d< real64 const > > const m_mob; - ElementViewConst< arrayView2d< real64 const > > const m_dMob_dPres; - ElementViewConst< arrayView2d< real64 const > > const m_dMob_dSat; + ElementViewConst< arrayView2d< real64 const, immiscibleFlow::USD_PHASE > > const m_mob; + ElementViewConst< arrayView3d< real64 const, immiscibleFlow::USD_PHASE_DS > > const m_dMob; /// Views on fluid density - ElementViewConst< arrayView2d< real64 const > > const m_dens; - ElementViewConst< arrayView2d< real64 const > > const m_dDens_dPres; + ElementViewConst< arrayView2d< real64 const, immiscibleFlow::USD_PHASE > > const m_dens; + ElementViewConst< arrayView2d< real64 const, immiscibleFlow::USD_PHASE > > const m_dDens_dPres; /// Views on capillary pressure - ElementViewConst< arrayView2d< real64 const > > const m_phaseCapPressure; - ElementViewConst< arrayView2d< real64 const > > const m_dPhaseCapPressure_dPhaseVolFrac; + ElementViewConst< arrayView3d< real64 const, cappres::USD_CAPPRES > > const m_phaseCapPressure; + ElementViewConst< arrayView4d< real64 const, cappres::USD_CAPPRES_DS > > const m_dPhaseCapPressure_dPhaseVolFrac; // Residual and jacobian @@ -239,7 +231,6 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase STENCILWRAPPER const & stencilWrapper, DofNumberAccessor const & dofNumberAccessor, ImmiscibleMultiphaseFlowAccessors const & multiPhaseFlowAccessors, - ImmiscibleMultiphaseFluidAccessors const & multiPhaseFluidAccessors, CapPressureAccessors const & capPressureAccessors, PermeabilityAccessors const & permeabilityAccessors, real64 const & dt, @@ -250,8 +241,7 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase : FaceBasedAssemblyKernelBase( numPhases, rankOffset, dofNumberAccessor, - multiPhaseFlowAccessors, - multiPhaseFluidAccessors, + multiPhaseFlowAccessors, capPressureAccessors, permeabilityAccessors, dt, @@ -383,18 +373,12 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase // clear working arrays real64 densMean[m_numPhases]{}; real64 dDensMean_dP[m_numPhases][2]{}; - // real64 densMean = 0.0; - // real64 dDensMean_dP[2]{0.0, 0.0}; - real64 presGrad[m_numPhases]{}; /// check need for vector + real64 presGrad[m_numPhases]{}; real64 dPresGrad_dP[m_numPhases][2]{}; - // real64 presGrad = 0.0; - // real64 dPresGrad_dP[2]{0.0, 0.0}; real64 gravHead[m_numPhases]{}; real64 dGravHead_dP[m_numPhases][2]{}; - // real64 gravHead = 0.0; - // real64 dGravHead_dP[2]{0.0, 0.0}; real64 capGrad[m_numPhases]{}; real64 dCapGrad_dP[m_numPhases][2]{}; @@ -403,8 +387,6 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase real64 fluxVal[m_numPhases]{}; real64 dFlux_dP[m_numPhases][2]{}; real64 dFlux_dS[m_numPhases][2]{}; - // real64 fluxVal = 0.0; - // real64 dFlux_dP[2]{0.0, 0.0}; real64 mobility[m_numPhases]{}; real64 dMob_dP[m_numPhases][2]{}; @@ -421,17 +403,16 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase // loop over phases for( integer ip = 0; ip < m_numPhases; ++ip ) { - // calculate quantities on primary connected cells for( integer ke = 0; ke < 2; ++ke ) { // density - real64 const density = m_dens[seri[ke]][sesri[ke]][sei[ke]][ip]; - real64 const dDens_dP = m_dDens_dPres[seri[ke]][sesri[ke]][sei[ke]][ip]; + real64 const density = m_dens[seri[ke]][sesri[ke]][sei[ke]][0][ip]; // r = rho1 || rho2 + real64 const dDens_dP = m_dDens_dPres[seri[ke]][sesri[ke]][sei[ke]][0][ip]; // dr/dP = dr1/dP1 || dr2/dP // average density and derivatives densMean[ip] += 0.5 * density; // rho = (rho1 + rho2) / 2 - dDensMean_dP[ip][ke] = 0.5 * dDens_dP; // drho/dP = { (drho1/dP)/2 , (drho2/dP)/2 } + dDensMean_dP[ip][ke] = 0.5 * dDens_dP; // drho/dP = { (dr1/dP1)/2 , (dr2/dP2)/2 } } //***** calculation of flux ***** @@ -452,7 +433,7 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase real64 const pressure = m_pres[er][esr][ei]; // P = P1 || P2 presGrad[ip] += trans[ke] * pressure; // DPv = T (P1 - P2) dPresGrad_dTrans += signPotDiff[ke] * pressure; // dDPv/dT = (P1 - P2) - dPresGrad_dP[ip][ke] = trans[ke]; // dDPv/dP = {T , -T} + dPresGrad_dP[ip][ke] = trans[ke]; // dDPv/dP = { T , -T } real64 const gravD = trans[ke] * m_gravCoef[er][esr][ei]; // D = T g z1 || -T g z2 real64 const pot = trans[ke] * pressure - densMean[ip] * gravD; // Phi = T P1 - rho T g z1 || -T P2 + rho T g z2 @@ -462,15 +443,15 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase for( integer i = 0; i < 2; ++i ) { - dGravHead_dP[ip][i] += dDensMean_dP[ip][i] * gravD; // dDPg/dP = {drho1/dP * T g (z1 - z2) , drho2/dP * T g (z1 - z2)} + dGravHead_dP[ip][i] += dDensMean_dP[ip][i] * gravD; // dDPg/dP = {drho/dP1 * T g (z1 - z2) , drho/dP2 * T g (z1 - z2)} } if ( m_hasCapPressure ) // check sign convention { - real64 const capPres = m_phaseCapPressure[er][esr][ei]; // Pc = Pc1 || Pc2 - dCapGrad_dTrans -= signPotDiff[ke] * capPres; // dDPc/dT = (-Pc1 + Pc2) - pot -= trans[ke] * capPres; // Phi = T P1 - rho T g z1 - T Pc1 || -T P2 + rho T g z2 + T Pc2 - capGrad[ip] -= trans[ke] * capPres; // DPc = T (-Pc1 + Pc2) + real64 const capPres = m_phaseCapPressure[er][esr][ei][0][ip]; // Pc = Pc1 || Pc2 + dCapGrad_dTrans -= signPotDiff[ke] * capPres; // dDPc/dT = (-Pc1 + Pc2) + pot -= trans[ke] * capPres; // Phi = T P1 - rho T g z1 - T Pc1 || -T P2 + rho T g z2 + T Pc2 + capGrad[ip] -= trans[ke] * capPres; // DPc = T (-Pc1 + Pc2) } potScale = fmax( potScale, fabs( pot ) ); // maxPhi = Phi1 > Phi2 ? Phi1 : Phi2 @@ -479,11 +460,14 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase for( integer ke = 0; ke < 2; ++ke ) { dPresGrad_dP[ip][ke] += dTrans_dP[ke] * dPresGrad_dTrans; // dDPv/dP = { T + dT/dP1 * (P1 - P2) , -T + dT/dP2 * (P1 - P2)} - dGravHead_dP[ip][ke] += dTrans_dP[ke] * dGravHead_dTrans; // dDPg/dP = { drho1/dP * T g (z1 - z2) + dT/dP1 * rho g (z1 - z2) , - // drho2/dP * T g (z1 - z2) + dT/dP2 * rho g (z1 - z2) } + dGravHead_dP[ip][ke] += dTrans_dP[ke] * dGravHead_dTrans; // dDPg/dP = { drho/dP1 * T g (z1 - z2) + dT/dP1 * rho g (z1 - z2) , + // drho/dP2 * T g (z1 - z2) + dT/dP2 * rho g (z1 - z2) } if ( m_hasCapPressure ) { - dCapGrad_dP[ip][ke] += dTrans_dP[ke] * dCapGrad_dTrans; // dDPc/dP = { dT/dP1 * (-Pc1 + Pc2) , dT/dP2 * (-Pc1 + Pc2) } + real64 const dCapPres_dS = m_dPhaseCapPressure_dPhaseVolFrac[seri[ke]][sesri[ke]][sei[ke]][0][ip][ip]; // dPc/dS = dPc1/dS1 || dPc2/dS2 + dCapGrad_dP[ip][ke] += dTrans_dP[ke] * dCapGrad_dTrans; // dDPc/dP = { dT/dP1 * (-Pc1 + Pc2) , + // dT/dP2 * (-Pc1 + Pc2) } + dCapGrad_dS[ip][ke] -= trans[ke] * dCapPres_dS; // dDPc/dS = { -T * dPc1/dS1 , T * dPc2/dS2 } } } @@ -504,24 +488,22 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase real64 const alpha = ( potGrad + upwAbsTol ) / ( 2 * upwAbsTol ); // alpha = (DPhi + abstol) / abstol / 2 // choose upstream cell - // real64 mobility{}; - // real64 dMob_dP[2]{}; if( alpha <= 0.0 || alpha >= 1.0 ) // no smoothing needed { localIndex const k_up = 1 - localIndex( fmax( fmin( alpha, 1.0 ), 0.0 ) ); // 1 upwind -> k_up = 0 || 2 upwind -> k_up = 1 - mobility[ip] = m_mob[seri[k_up]][sesri[k_up]][sei[k_up]][ip]; // M = Mupstream - dMob_dP[ip][k_up] = m_dMob_dPres[seri[k_up]][sesri[k_up]][sei[k_up]][ip]; // dM/dP = {dM/dP1 , 0} OR {0 , dM/dP2} - dMob_dS[ip][k_up] = m_dMob_dSat[seri[k_up]][sesri[k_up]][sei[k_up]][ip]; // dM/dS = {dM/dS1 , 0} OR {0 , dM/dS2} + mobility[ip] = m_mob[seri[k_up]][sesri[k_up]][sei[k_up]][0][ip]; // M = Mupstream + dMob_dP[ip][k_up] = m_dMob[seri[k_up]][sesri[k_up]][sei[k_up]][0][ip][Deriv::dP]; // dM/dP = {dM/dP1 , 0} OR {0 , dM/dP2} + dMob_dS[ip][k_up] = m_dMob[seri[k_up]][sesri[k_up]][sei[k_up]][0][ip][Deriv::dS]; // dM/dS = {dM/dS1 , 0} OR {0 , dM/dS2} } else // perform smoothing { real64 const mobWeights[2] = { alpha, 1.0 - alpha }; for( integer ke = 0; ke < 2; ++ke ) { - mobility[ip] += mobWeights[ke] * m_mob[seri[ke]][sesri[ke]][sei[ke]][ip]; // M = alpha * M1 + (1 - alpha) * M2 - dMob_dP[ip][ke] = mobWeights[ke] * m_dMob_dPres[seri[ke]][sesri[ke]][sei[ke]][ip]; // dM/dP = {alpha * dM1/dP1 , (1 - alpha) * dM2/dP2} - dMob_dS[ip][ke] = mobWeights[ke] * m_dMob_dSat[seri[ke]][sesri[ke]][sei[ke]][ip]; // dM/dP = {alpha * dM1/dS1 , (1 - alpha) * dM2/dS2} + mobility[ip] += mobWeights[ke] * m_mob[seri[ke]][sesri[ke]][sei[ke]][0][ip]; // M = alpha * M1 + (1 - alpha) * M2 + dMob_dP[ip][ke] = mobWeights[ke] * m_dMob[seri[ke]][sesri[ke]][sei[ke]][0][ip][Deriv::dP]; // dM/dP = {alpha * dM1/dP1 , (1 - alpha) * dM2/dP2} + dMob_dS[ip][ke] = mobWeights[ke] * m_dMob[seri[ke]][sesri[ke]][sei[ke]][0][ip][Deriv::dS]; // dM/dP = {alpha * dM1/dS1 , (1 - alpha) * dM2/dS2} } } @@ -535,8 +517,8 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase // gravitational head depends only on the two cells connected (same as mean density) for( integer ke = 0; ke < 2; ++ke ) { - dFlux_dP[ip][ke] -= dGravHead_dP[ip][ke]; // dF/dP = { T + dT/dP1 * (P1 - P2) - drho1/dP * T g (z1 - z2) - dT/dP1 * rho g (z1 - z2) , - // -T + dT/dP2 * (P1 - P2) - drho2/dP * T g (z1 - z2) - dT/dP2 * rho g (z1 - z2) } + dFlux_dP[ip][ke] -= dGravHead_dP[ip][ke]; // dF/dP = { T + dT/dP1 * (P1 - P2) - drho/dP1 * T g (z1 - z2) - dT/dP1 * rho g (z1 - z2) , + // -T + dT/dP2 * (P1 - P2) - drho/dP2 * T g (z1 - z2) - dT/dP2 * rho g (z1 - z2) } } // capillary pressure contribution @@ -544,8 +526,10 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase { for( integer ke = 0; ke < 2; ++ke ) { - dFlux_dP[ip][ke] += dCapGrad_dP[ip][ke]; // dF/dP = { T + dT/dP1 * (P1 - P2) - drho1/dP * T g (z1 - z2) - dT/dP1 * rho g (z1 - z2) + dT/dP1 * (-Pc1 + Pc2) , - // -T + dT/dP2 * (P1 - P2) - drho2/dP * T g (z1 - z2) - dT/dP2 * rho g (z1 - z2) + dT/dP2 * (-Pc1 + Pc2) } + dFlux_dP[ip][ke] += dCapGrad_dP[ip][ke]; // dF/dP = { T + dT/dP1 * (P1 - P2) - drho/dP1 * T g (z1 - z2) - dT/dP1 * rho g (z1 - z2) + dT/dP1 * (-Pc1 + Pc2) , + // -T + dT/dP2 * (P1 - P2) - drho/dP2 * T g (z1 - z2) - dT/dP2 * rho g (z1 - z2) + dT/dP2 * (-Pc1 + Pc2) } + + dFlux_dS[ip][ke] += dCapGrad_dS[ip][ke]; // dF/dS = { T * -dPc/dS1 , T * dPc/dS2 } } } @@ -554,8 +538,10 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase for( integer ke = 0; ke < 2; ++ke ) { - dFlux_dP[ip][ke] *= mobility[ip]; // dF/dP = { M [ T + dT/dP1 * (P1 - P2) - drho1/dP * T g (z1 - z2) - dT/dP1 * rho g (z1 - z2) + dT/dP1 * (-Pc1 + Pc2)] , - // M [-T + dT/dP2 * (P1 - P2) - drho2/dP * T g (z1 - z2) - dT/dP2 * rho g (z1 - z2) + dT/dP2 * (-Pc1 + Pc2)] } + dFlux_dP[ip][ke] *= mobility[ip]; // dF/dP = { M [ T + dT/dP1 * (P1 - P2) - drho/dP1 * T g (z1 - z2) - dT/dP1 * rho g (z1 - z2) + dT/dP1 * (-Pc1 + Pc2)] , + // M [-T + dT/dP2 * (P1 - P2) - drho/dP2 * T g (z1 - z2) - dT/dP2 * rho g (z1 - z2) + dT/dP2 * (-Pc1 + Pc2)] } + + dFlux_dS[ip][ke] *= mobility[ip]; // dF/dS = { M [T * -dPc/dS1] , M [T * dPc/dS2] } } // add contribution from upstream cell mobility derivatives @@ -564,7 +550,7 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase dFlux_dP[ip][ke] += dMob_dP[ip][ke] * potGrad; // dF/dP = { M [ T + dT/dP1 * (P1 - P2) - drho1/dP * T g (z1 - z2) - dT/dP1 * rho g (z1 - z2) + dT/dP1 * (-Pc1 + Pc2)] + dM/dP1 * DPhi , // M [-T + dT/dP2 * (P1 - P2) - drho2/dP * T g (z1 - z2) - dT/dP2 * rho g (z1 - z2) + dT/dP2 * (-Pc1 + Pc2)] + dM/dP2 * DPhi } - dFlux_dS[ip][ke] += dMob_dS[ip][ke] * potGrad; // dF/dS = { dM/dS1 * DPhi , dM/dS2 * DPhi } + dFlux_dS[ip][ke] += dMob_dS[ip][ke] * potGrad; // dF/dS = { M [T * -dPc/dS1] + dM/dS1 * DPhi , M [T * dPc/dS2] + dM/dS2 * DPhi } } // populate local flux vector and derivatives @@ -698,7 +684,7 @@ class FaceBasedAssemblyKernelFactory template< typename POLICY, typename STENCILWRAPPER > static void createAndLaunch( integer const numPhases, - globalIndex const rankOffset, // add capillary pressure and total mass equation flags + globalIndex const rankOffset, string const & dofKey, integer const hasCapPressure, integer const useTotalMassEquation, @@ -717,13 +703,12 @@ class FaceBasedAssemblyKernelFactory dofNumberAccessor.setName( solverName + "/accessors/" + dofKey ); using kernelType = FaceBasedAssemblyKernel< NUM_EQN, NUM_DOF, STENCILWRAPPER >; - typename kernelType::ImmiscibleMultiPhaseFlowAccessors flowAccessors( elemManager, solverName ); - typename kernelType::ImmiscibleMultiPhaseFluidAccessors fluidAccessors( elemManager, solverName ); + typename kernelType::ImmiscibleMultiPhaseFlowAccessors flowAccessors( elemManager, solverName ); typename kernelType::CapPressureAccessors capPressureAccessors( elemManager, solverName ); typename kernelType::PermeabilityAccessors permAccessors( elemManager, solverName ); kernelType kernel( numPhases, rankOffset, stencilWrapper, dofNumberAccessor, - flowAccessors, fluidAccessors, capPressureAccessors, permAccessors, + flowAccessors, capPressureAccessors, permAccessors, dt, localMatrix, localRhs, hasCapPressure, useTotalMassEquation ); kernelType::template launch< POLICY >( stencilWrapper.size(), kernel ); } @@ -731,7 +716,6 @@ class FaceBasedAssemblyKernelFactory - } // namesace immiscible multiphasekernels From 40e191a663a1c599d244e1d0e3a87ece8711ff71 Mon Sep 17 00:00:00 2001 From: rpiazza87 Date: Mon, 19 Aug 2024 18:08:50 -0700 Subject: [PATCH 021/102] added phase mobility kernel --- .../fluidFlow/ImmiscibleMultiphaseFlow.cpp | 27 ++- .../fluidFlow/ImmiscibleMultiphaseKernels.hpp | 155 ++++++++++++++++++ 2 files changed, 165 insertions(+), 17 deletions(-) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp index a5a5c3491a2..6e34cb6072e 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp @@ -271,24 +271,17 @@ void ImmiscibleMultiphaseFlow::updateFluidState( ElementSubRegionBase & subRegio void ImmiscibleMultiphaseFlow::updatePhaseMobility( ObjectManagerBase & dataGroup ) const { GEOS_MARK_FUNCTION; - - GEOS_UNUSED_VAR( dataGroup ); - /// Matteo: looks like you will to create a new update function for the mobility. I have left the code as an example. - // // note that the phase mobility computed here also includes phase density - // string const & fluidName = dataGroup.getReference< string >( viewKeyStruct::fluidNamesString() ); - // MultiFluidBase const & fluid = getConstitutiveModel< MultiFluidBase >( dataGroup, fluidName ); - - // string const & relpermName = dataGroup.getReference< string >( viewKeyStruct::relPermNamesString() ); - // RelativePermeabilityBase const & relperm = getConstitutiveModel< RelativePermeabilityBase >( dataGroup, relpermName ); - - // isothermalCompositionalMultiphaseFVMKernels:: - // PhaseMobilityKernelFactory:: - // createAndLaunch< parallelDevicePolicy<> >( m_numComponents, - // m_numPhases, - // dataGroup, - // fluid, - // relperm ); + // note that the phase mobility computed here also includes phase density + string const & relpermName = dataGroup.getReference< string >( viewKeyStruct::relPermNamesString() ); + RelativePermeabilityBase const & relperm = getConstitutiveModel< RelativePermeabilityBase >( dataGroup, relpermName ); + + immiscibleMultiphaseKernels:: + PhaseMobilityKernelFactory:: + createAndLaunch< parallelDevicePolicy<> >( m_numPhases, + dataGroup, + relperm ); + } void ImmiscibleMultiphaseFlow::initializeFluidState( MeshLevel & mesh, diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseKernels.hpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseKernels.hpp index 310f7e34c07..912a9ce8509 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseKernels.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseKernels.hpp @@ -714,6 +714,161 @@ class FaceBasedAssemblyKernelFactory } }; +/******************************** PhaseMobilityKernel ********************************/ + +/** + * @class PhaseMobilityKernel + * @tparam NUM_PHASE number of fluid phases + * @brief Define the interface for the property kernel in charge of computing the phase mobilities + */ +template< integer NUM_PHASE > +class PhaseMobilityKernel +{ +public: + + //using Base = isothermalCompositionalMultiphaseBaseKernels::PropertyKernelBase< NUM_COMP >; + + /// Compile time value for the number of phases + static constexpr integer numPhase = NUM_PHASE; + + /** + * @brief Constructor + * @param[in] subRegion the element subregion + * @param[in] fluid the fluid model + * @param[in] relperm the relperm model + */ + PhaseMobilityKernel( ObjectManagerBase & subRegion, + RelativePermeabilityBase const & relperm ) + : + m_phaseDens( subRegion.getField< fields::immiscibleMultiphaseFlow::phaseDensity >() ), + m_dPhaseDens( subRegion.getField< fields::immiscibleMultiphaseFlow::dPhaseDensity>() ), + m_phaseVisc( subRegion.getField< fields::immiscibleMultiphaseFlow::phaseViscosity >() ), + m_dPhaseVisc( subRegion.getField< fields::immiscibleMultiphaseFlow::dPhaseViscosity >() ), + m_phaseRelPerm( relperm.phaseRelPerm() ), + m_dPhaseRelPerm_dPhaseVolFrac( relperm.dPhaseRelPerm_dPhaseVolFraction() ), + m_phaseMob( subRegion.getField< fields::immiscibleMultiphaseFlow::phaseMobility >() ), + m_dPhaseMob( subRegion.getField< fields::immiscibleMultiphaseFlow::dPhaseMobility >() ) + {} + + /** + * @brief Performs the kernel launch + * @tparam POLICY the policy used in the RAJA kernels + * @tparam KERNEL_TYPE the kernel type + * @param[in] numElems the number of elements + * @param[inout] kernelComponent the kernel component providing access to the compute function + */ + template< typename POLICY, typename KERNEL_TYPE > + static void + launch( localIndex const numElems, + KERNEL_TYPE const & kernelComponent ) + { + forAll< POLICY >( numElems, [=] GEOS_HOST_DEVICE ( localIndex const ei ) + { + kernelComponent.compute( ei ); + } ); + } + + /** + * @brief Compute the phase mobilities in an element + * @tparam FUNC the type of the function that can be used to customize the kernel + * @param[in] ei the element index + * @param[in] phaseMobilityKernelOp the function used to customize the kernel + */ + template< typename FUNC = NoOpFunc > + GEOS_HOST_DEVICE + void compute( localIndex const ei, + FUNC && phaseMobilityKernelOp = NoOpFunc{} ) const + { + using Deriv = immiscibleFlow::DerivativeOffset; + + arraySlice1d< real64, immiscibleFlow::USD_PHASE - 1 > const phaseMob = m_phaseMob[ei]; + arraySlice2d< real64, immiscibleFlow::USD_PHASE_DS - 1 > const dPhaseMob = m_dPhaseMob[ei]; + + for( integer ip = 0; ip < numPhase; ++ip ) + { + real64 const density = m_phaseDens[ei][0][ip]; + real64 const dDens_dP = m_dPhaseDens[ei][0][ip]; + real64 const viscosity = m_phaseVisc[ei][0][ip]; + real64 const dVisc_dP = m_dPhaseVisc[ei][0][ip]; + + real64 const relPerm = m_phaseRelPerm[ei][0][ip]; + + real64 const mobility = relPerm * density / viscosity; + + phaseMob[ip] = mobility; + dPhaseMob[ip][Deriv::dP] = mobility * (dDens_dP / density - dVisc_dP / viscosity); + + for( integer jp = 0; jp < numPhase; ++jp ) // check if we need numPhase or numPhase-1 derivatives + { + real64 const dRelPerm_dS = dPhaseRelPerm_dPhaseVolFrac[ei][0][ip][jp]; + dPhaseMob[ip][Deriv::dS+jp] = dRelPerm_dS * density / viscosity; + } + + // call the lambda in the phase loop to allow the reuse of the relperm, density, viscosity, and mobility + // possible use: assemble the derivatives wrt temperature + phaseMobilityKernelOp( ip, phaseMob[ip], dPhaseMob[ip] ); + } + } + +protected: + + // inputs + + /// Views on the phase densities + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > m_phaseDens; + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > m_dPhaseDens; + + /// Views on the phase viscosities + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > m_phaseVisc; + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > m_dPhaseVisc; + + /// Views on the phase relative permeabilities + arrayView3d< real64 const, relperm::USD_RELPERM > m_phaseRelPerm; + arrayView4d< real64 const, relperm::USD_RELPERM_DS > m_dPhaseRelPerm_dPhaseVolFrac; + + // outputs + + /// Views on the phase mobilities + arrayView2d< real64, immiscibleFlow::USD_PHASE > m_phaseMob; + arrayView3d< real64, immiscibleFlow::USD_PHASE_DS > m_dPhaseMob; +}; + +/** + * @class PhaseMobilityKernelFactory + */ +class PhaseMobilityKernelFactory +{ +public: + + /** + * @brief Create a new kernel and launch + * @tparam POLICY the policy used in the RAJA kernel + * @param[in] numPhase the number of fluid phases + * @param[in] subRegion the element subregion + * @param[in] relperm the relperm model + */ + template< typename POLICY > + static void + createAndLaunch( integer const numPhase, + ObjectManagerBase & subRegion, + RelativePermeabilityBase const & relperm ) + { + if( numPhase == 2 ) + { + PhaseMobilityKernel< 2 > kernel( subRegion, relperm ); + PhaseMobilityKernel< 2 >::template launch< POLICY >( subRegion.size(), kernel ); + } + else if( numPhase == 3 ) + { + PhaseMobilityKernel< 3 > kernel( subRegion, relperm ); + PhaseMobilityKernel< 3 >::template launch< POLICY >( subRegion.size(), kernel ); + } + } + +}; + + + } // namesace immiscible multiphasekernels From cb15c3005b789175f121113395aa5831f9132edb Mon Sep 17 00:00:00 2001 From: rpiazza87 Date: Tue, 20 Aug 2024 14:58:59 -0700 Subject: [PATCH 022/102] updated kernels, apply BC and setupDOF --- src/coreComponents/common/DataLayouts.hpp | 5 +- .../fluidFlow/ImmiscibleMultiphaseFlow.cpp | 136 +++++++++++++++--- .../ImmiscibleMultiphaseFlowFields.hpp | 8 ++ .../fluidFlow/ImmiscibleMultiphaseKernels.hpp | 92 ++++++------ 4 files changed, 175 insertions(+), 66 deletions(-) diff --git a/src/coreComponents/common/DataLayouts.hpp b/src/coreComponents/common/DataLayouts.hpp index 40b64ada6df..e09fe788d65 100644 --- a/src/coreComponents/common/DataLayouts.hpp +++ b/src/coreComponents/common/DataLayouts.hpp @@ -21,6 +21,7 @@ #define GEOS_COMMON_DATALAYOUTS_HPP_ #include "common/GeosxConfig.hpp" +#include "common/DataTypes.hpp" #include "LvArray/src/Array.hpp" #include "RAJA/RAJA.hpp" @@ -236,9 +237,9 @@ static constexpr int USD_PHASE_DS = LvArray::typeManipulation::getStrideOneDimen struct DerivativeOffset { /// index of derivative wrt pressure - static integer constexpr dP = 0; + static int constexpr dP = 0; /// index of first derivative wrt compositions - static integer constexpr dS = 1; + static int constexpr dS = 1; }; } // namespace immiscibleFlow diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp index 6e34cb6072e..9d3594d71f8 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp @@ -23,6 +23,9 @@ #include "physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlowFields.hpp" #include "physicsSolvers/fluidFlow/ImmiscibleMultiphaseKernels.hpp" +#include "physicsSolvers/fluidFlow/IsothermalCompositionalMultiphaseBaseKernels.hpp" // should be removed eventually +#include "physicsSolvers/fluidFlow/IsothermalCompositionalMultiphaseFVMKernels.hpp" + #include "constitutive/ConstitutiveManager.hpp" #include "constitutive/capillaryPressure/CapillaryPressureFields.hpp" #include "constitutive/capillaryPressure/capillaryPressureSelector.hpp" @@ -69,7 +72,8 @@ ImmiscibleMultiphaseFlow::ImmiscibleMultiphaseFlow( const string & name, : FlowSolverBase( name, parent ), m_numPhases( 2 ), - m_hasCapPressure( 0 ) + m_hasCapPressure( 0 ), + m_useTotalMassEquation ( 0 ) { this->registerWrapper( viewKeyStruct::inputTemperatureString(), &m_inputTemperature ). setInputFlag( InputFlags::REQUIRED ). @@ -640,9 +644,7 @@ void ImmiscibleMultiphaseFlow::assembleFluxTerms( real64 const dt, DofManager const & dofManager, CRSMatrixView< real64, globalIndex const > const & localMatrix, arrayView1d< real64 > const & localRhs ) const -{ - GEOS_UNUSED_VAR( dt, domain, dofManager, localMatrix, localRhs ); - +{ GEOS_MARK_FUNCTION; NumericalMethodsManager const & numericalMethodManager = domain.getNumericalMethodManager(); @@ -657,6 +659,8 @@ void ImmiscibleMultiphaseFlow::assembleFluxTerms( real64 const dt, { fluxApprox.forAllStencils( mesh, [&]( auto & stencil ) { + typename TYPEOFREF( stencil ) ::KernelWrapper stencilWrapper = stencil.createKernelWrapper(); + immiscibleMultiphaseKernels:: FaceBasedAssemblyKernelFactory::createAndLaunch< parallelDevicePolicy<> >( m_numPhases, dofManager.rankOffset(), dofKey, @@ -678,26 +682,20 @@ void ImmiscibleMultiphaseFlow::setupDofs( DomainPartition const & domain, DofManager & dofManager ) const { GEOS_UNUSED_VAR(domain, dofManager); - //// add a field for the cell-centered degrees of freedom - //dofManager.addField( viewKeyStruct::elemDofFieldString(), - // FieldLocation::Elem, - // m_numDofPerCell, - // getMeshTargets() ); + // add a field for the cell-centered degrees of freedom + dofManager.addField( viewKeyStruct::elemDofFieldString(), + FieldLocation::Elem, + m_numDofPerCell, + getMeshTargets() ); //// this call with instruct GEOS to reorder the dof numbers //dofManager.setLocalReorderingType( viewKeyStruct::elemDofFieldString(), // DofManager::LocalReorderingType::ReverseCutHillMcKee ); - //// for the volume balance equation, disable global coupling - //// this equation is purely local (not coupled to neighbors or other physics) - //dofManager.disableGlobalCouplingForEquation( viewKeyStruct::elemDofFieldString(), - // m_numComponents ); - - - //NumericalMethodsManager const & numericalMethodManager = domain.getNumericalMethodManager(); - //FiniteVolumeManager const & fvManager = numericalMethodManager.getFiniteVolumeManager(); - //FluxApproximationBase const & fluxApprox = fvManager.getFluxApproximation( m_discretizationName ); - //dofManager.addCoupling( viewKeyStruct::elemDofFieldString(), fluxApprox ); + NumericalMethodsManager const & numericalMethodManager = domain.getNumericalMethodManager(); + FiniteVolumeManager const & fvManager = numericalMethodManager.getFiniteVolumeManager(); + FluxApproximationBase const & fluxApprox = fvManager.getFluxApproximation( m_discretizationName ); + dofManager.addCoupling( viewKeyStruct::elemDofFieldString(), fluxApprox ); } void ImmiscibleMultiphaseFlow::applyBoundaryConditions( real64 const time_n, @@ -713,14 +711,110 @@ void ImmiscibleMultiphaseFlow::applyBoundaryConditions( real64 const time_n, applyDirichletBC( time_n, dt, dofManager, domain, localMatrix.toViewConstSizes(), localRhs.toView() ); } -void ImmiscibleMultiphaseFlow::applyDirichletBC( real64 const time, +namespace +{ +char const bcLogMessage[] = + "CompositionalMultiphaseBase {}: at time {}s, " + "the <{}> boundary condition '{}' is applied to the element set '{}' in subRegion '{}'. " + "\nThe scale of this boundary condition is {} and multiplies the value of the provided function (if any). " + "\nThe total number of target elements (including ghost elements) is {}. " + "\nNote that if this number is equal to zero for all subRegions, the boundary condition will not be applied on this element set."; +} + +void ImmiscibleMultiphaseFlow::applyDirichletBC( real64 const time_n, real64 const dt, DofManager const & dofManager, DomainPartition & domain, CRSMatrixView< real64, globalIndex const > const & localMatrix, arrayView1d< real64 > const & localRhs ) const { - GEOS_UNUSED_VAR( time, dt, dofManager, domain, localMatrix, localRhs ); + GEOS_MARK_FUNCTION; + + // // Only validate BC at the beginning of Newton loop + // if( m_nonlinearSolverParameters.m_numNewtonIterations == 0 ) + // { + // bool const bcConsistent = validateDirichletBC( domain, time_n + dt ); + // GEOS_ERROR_IF( !bcConsistent, GEOS_FMT( "CompositionalMultiphaseBase {}: inconsistent boundary conditions", getDataContext() ) ); + // } + + FieldSpecificationManager & fsManager = FieldSpecificationManager::getInstance(); + + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, + MeshLevel & mesh, + arrayView1d< string const > const & ) + { + + // 1. Apply pressure Dirichlet BCs, store in a separate field + applyFieldValue< ElementSubRegionBase >( time_n, dt, mesh, bcLogMessage, + fields::flow::pressure::key(), fields::flow::bcPressure::key() ); + // 2. Apply saturation BC (phase volume fraction) and store in a separate field + applyFieldValue< ElementSubRegionBase >( time_n, dt, mesh, bcLogMessage, + fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key(), fields::immiscibleMultiphaseFlow::bcPhaseVolumeFraction::key() ); + + globalIndex const rankOffset = dofManager.rankOffset(); + string const dofKey = dofManager.getKey( viewKeyStruct::elemDofFieldString() ); + + // 3. Call constitutive update, back-calculate target global component densities and apply to the system + fsManager.apply< ElementSubRegionBase >( time_n + dt, + mesh, + fields::flow::pressure::key(), + [&] ( FieldSpecificationBase const &, + string const &, + SortedArrayView< localIndex const > const & targetSet, + ElementSubRegionBase & subRegion, + string const & ) + { + + arrayView1d< real64 const > const bcPres = + subRegion.getReference< array1d< real64 > >( fields::flow::bcPressure::key() ); + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const bcPhaseVolFraction = + subRegion.getReference< array2d< real64, immiscibleFlow::LAYOUT_PHASE > >( fields::immiscibleMultiphaseFlow::bcPhaseVolumeFraction::key() ); + + arrayView1d< integer const > const ghostRank = + subRegion.getReference< array1d< integer > >( ObjectManagerBase::viewKeyStruct::ghostRankString() ); + arrayView1d< globalIndex const > const dofNumber = + subRegion.getReference< array1d< globalIndex > >( dofKey ); + arrayView1d< real64 const > const pres = + subRegion.getReference< array1d< real64 > >( fields::flow::pressure::key() ); + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFraction = + subRegion.getReference< array2d< real64, immiscibleFlow::LAYOUT_PHASE > >( fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key() ); + + integer const numPhase = m_numPhases; + forAll< parallelDevicePolicy<> >( targetSet.size(), [=] GEOS_HOST_DEVICE ( localIndex const a ) + { + localIndex const ei = targetSet[a]; + if( ghostRank[ei] >= 0 ) + { + return; + } + + globalIndex const dofIndex = dofNumber[ei]; + localIndex const localRow = dofIndex - rankOffset; + real64 rhsValue; + + // 3.1. Apply pressure value to the matrix/rhs + FieldSpecificationEqual::SpecifyFieldValue( dofIndex, + rankOffset, + localMatrix, + rhsValue, + bcPres[ei], + pres[ei] ); + localRhs[localRow] = rhsValue; + + // 3.2. For each phase, apply target saturation value + for( integer ip = 0; ip < numPhase; ++ip ) + { + FieldSpecificationEqual::SpecifyFieldValue( dofIndex + ip + 1, + rankOffset, + localMatrix, + rhsValue, + bcPhaseVolFraction[ei][ip], + phaseVolFraction[ei][ip] ); + localRhs[localRow + ip + 1] = rhsValue; + } + } ); + } ); + } ); } void ImmiscibleMultiphaseFlow::resetStateToBeginningOfStep( DomainPartition & domain ) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlowFields.hpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlowFields.hpp index dcf303e6eca..0cde6c89fad 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlowFields.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlowFields.hpp @@ -53,6 +53,14 @@ DECLARE_FIELD( phaseVolumeFraction_n, WRITE_AND_READ, "Phase volume fraction at the previous converged time step" ); +DECLARE_FIELD( bcPhaseVolumeFraction, + "bcPhaseVolumeFraction", + array2dLayoutPhase, + 0, + LEVEL_0, + WRITE_AND_READ, + "Boundary condition phase volume fraction" ); + DECLARE_FIELD( phaseMass, "phaseMass", array2dLayoutPhase, diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseKernels.hpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseKernels.hpp index 912a9ce8509..63e562674cb 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseKernels.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseKernels.hpp @@ -71,11 +71,13 @@ class FaceBasedAssemblyKernelBase using ImmiscibleMultiphaseFlowAccessors = StencilAccessors< fields::ghostRank, fields::flow::pressure, - fields::flow::gravityCoefficient, - fields::immiscibleMultiphaseFlow::phaseDensity, - fields::immiscibleMultiphaseFlow::dPhaseDensity, + fields::flow::gravityCoefficient, fields::immiscibleMultiphaseFlow::phaseMobility, - fields::immiscibleMultiphaseFlow::dPhaseMobility >; + fields::immiscibleMultiphaseFlow::dPhaseMobility >; + + using MultiphaseFluidAccessors = + StencilAccessors< fields::immiscibleMultiphaseFlow::phaseDensity, + fields::immiscibleMultiphaseFlow::dPhaseDensity >; using CapPressureAccessors = StencilMaterialAccessors< CapillaryPressureBase, @@ -104,7 +106,8 @@ class FaceBasedAssemblyKernelBase FaceBasedAssemblyKernelBase( integer const numPhases, globalIndex const rankOffset, DofNumberAccessor const & dofNumberAccessor, - ImmiscibleMultiphaseFlowAccessors const & multiPhaseFlowAccessors, + ImmiscibleMultiphaseFlowAccessors const & multiPhaseFlowAccessors, + MultiphaseFluidAccessors const & fluidAccessors, CapPressureAccessors const & capPressureAccessors, PermeabilityAccessors const & permeabilityAccessors, real64 const & dt, @@ -123,15 +126,15 @@ class FaceBasedAssemblyKernelBase m_pres( multiPhaseFlowAccessors.get( fields::flow::pressure {} ) ), m_mob( multiPhaseFlowAccessors.get( fields::immiscibleMultiphaseFlow::phaseMobility {} ) ), m_dMob( multiPhaseFlowAccessors.get( fields::immiscibleMultiphaseFlow::dPhaseMobility {} ) ), - m_dens( multiPhaseFlowAccessors.get( fields::immiscibleMultiphaseFlow::phaseDensity {} ) ), - m_dDens_dPres( multiPhaseFlowAccessors.get( fields::immiscibleMultiphaseFlow::dPhaseDensity {} ) ), + m_dens( fluidAccessors.get( fields::immiscibleMultiphaseFlow::phaseDensity {} ) ), + m_dDens_dPres( fluidAccessors.get( fields::immiscibleMultiphaseFlow::dPhaseDensity {} ) ), m_phaseCapPressure( capPressureAccessors.get( fields::cappres::phaseCapPressure {} ) ), m_dPhaseCapPressure_dPhaseVolFrac( capPressureAccessors.get( fields::cappres::dPhaseCapPressure_dPhaseVolFraction {} ) ), m_localMatrix( localMatrix ), m_localRhs( localRhs ), m_hasCapPressure ( hasCapPressure ), m_useTotalMassEquation ( useTotalMassEquation ) - {} + {GEOS_UNUSED_VAR(m_useTotalMassEquation);} protected: @@ -231,6 +234,7 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase STENCILWRAPPER const & stencilWrapper, DofNumberAccessor const & dofNumberAccessor, ImmiscibleMultiphaseFlowAccessors const & multiPhaseFlowAccessors, + MultiphaseFluidAccessors const & fluidAccessors, CapPressureAccessors const & capPressureAccessors, PermeabilityAccessors const & permeabilityAccessors, real64 const & dt, @@ -241,7 +245,8 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase : FaceBasedAssemblyKernelBase( numPhases, rankOffset, dofNumberAccessor, - multiPhaseFlowAccessors, + multiPhaseFlowAccessors, + fluidAccessors, capPressureAccessors, permeabilityAccessors, dt, @@ -371,26 +376,26 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase for( k[1] = k[0] + 1; k[1] < stack.numFluxElems; ++k[1] ) { // clear working arrays - real64 densMean[m_numPhases]{}; - real64 dDensMean_dP[m_numPhases][2]{}; + real64 densMean[numEqn]{}; + real64 dDensMean_dP[numEqn][2]{}; - real64 presGrad[m_numPhases]{}; - real64 dPresGrad_dP[m_numPhases][2]{}; + real64 presGrad[numEqn]{}; + real64 dPresGrad_dP[numEqn][2]{}; - real64 gravHead[m_numPhases]{}; - real64 dGravHead_dP[m_numPhases][2]{}; + real64 gravHead[numEqn]{}; + real64 dGravHead_dP[numEqn][2]{}; - real64 capGrad[m_numPhases]{}; - real64 dCapGrad_dP[m_numPhases][2]{}; - real64 dCapGrad_dS[m_numPhases][2]{}; + real64 capGrad[numEqn]{}; + real64 dCapGrad_dP[numEqn][2]{}; + real64 dCapGrad_dS[numEqn][2]{}; - real64 fluxVal[m_numPhases]{}; - real64 dFlux_dP[m_numPhases][2]{}; - real64 dFlux_dS[m_numPhases][2]{}; + real64 fluxVal[numEqn]{}; + real64 dFlux_dP[numEqn][2]{}; + real64 dFlux_dS[numEqn][2]{}; - real64 mobility[m_numPhases]{}; - real64 dMob_dP[m_numPhases][2]{}; - real64 dMob_dS[m_numPhases][2]{}; + real64 mobility[numEqn]{}; + real64 dMob_dP[numEqn][2]{}; + real64 dMob_dS[numEqn][2]{}; real64 const trans[2] = { stack.transmissibility[connectionIndex][0], stack.transmissibility[connectionIndex][1] }; real64 const dTrans_dP[2] = { stack.dTrans_dPres[connectionIndex][0], stack.dTrans_dPres[connectionIndex][1] }; @@ -407,8 +412,8 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase for( integer ke = 0; ke < 2; ++ke ) { // density - real64 const density = m_dens[seri[ke]][sesri[ke]][sei[ke]][0][ip]; // r = rho1 || rho2 - real64 const dDens_dP = m_dDens_dPres[seri[ke]][sesri[ke]][sei[ke]][0][ip]; // dr/dP = dr1/dP1 || dr2/dP + real64 const density = m_dens[seri[ke]][sesri[ke]][sei[ke]][ip]; // r = rho1 || rho2 + real64 const dDens_dP = m_dDens_dPres[seri[ke]][sesri[ke]][sei[ke]][ip]; // dr/dP = dr1/dP1 || dr2/dP // average density and derivatives densMean[ip] += 0.5 * density; // rho = (rho1 + rho2) / 2 @@ -436,7 +441,7 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase dPresGrad_dP[ip][ke] = trans[ke]; // dDPv/dP = { T , -T } real64 const gravD = trans[ke] * m_gravCoef[er][esr][ei]; // D = T g z1 || -T g z2 - real64 const pot = trans[ke] * pressure - densMean[ip] * gravD; // Phi = T P1 - rho T g z1 || -T P2 + rho T g z2 + real64 pot = trans[ke] * pressure - densMean[ip] * gravD; // Phi = T P1 - rho T g z1 || -T P2 + rho T g z2 gravHead[ip] += densMean[ip] * gravD; // DPg = rho (T g z1 - T g z2) = T rho g (z1 - z2) dGravHead_dTrans += signPotDiff[ke] * densMean[ip] * m_gravCoef[er][esr][ei]; // dDPg/dT = rho g z1 - rho g z2 = rho g (z1 - z2) @@ -474,7 +479,7 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase // *** upwinding *** // compute potential gradient - real64 const potGrad = presGrad[ip] - gravHead[ip]; // DPhi = T (P1 - P2) - T rho g (z1 - z2) + real64 potGrad = presGrad[ip] - gravHead[ip]; // DPhi = T (P1 - P2) - T rho g (z1 - z2) if ( m_hasCapPressure ) { potGrad += capGrad[ip]; // DPhi = T (P1 - P2) - T rho g (z1 - z2) + T (-Pc1 + Pc2) @@ -492,18 +497,18 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase { localIndex const k_up = 1 - localIndex( fmax( fmin( alpha, 1.0 ), 0.0 ) ); // 1 upwind -> k_up = 0 || 2 upwind -> k_up = 1 - mobility[ip] = m_mob[seri[k_up]][sesri[k_up]][sei[k_up]][0][ip]; // M = Mupstream - dMob_dP[ip][k_up] = m_dMob[seri[k_up]][sesri[k_up]][sei[k_up]][0][ip][Deriv::dP]; // dM/dP = {dM/dP1 , 0} OR {0 , dM/dP2} - dMob_dS[ip][k_up] = m_dMob[seri[k_up]][sesri[k_up]][sei[k_up]][0][ip][Deriv::dS]; // dM/dS = {dM/dS1 , 0} OR {0 , dM/dS2} + mobility[ip] = m_mob[seri[k_up]][sesri[k_up]][sei[k_up]][ip]; // M = Mupstream + dMob_dP[ip][k_up] = m_dMob[seri[k_up]][sesri[k_up]][sei[k_up]][ip][Deriv::dP]; // dM/dP = {dM/dP1 , 0} OR {0 , dM/dP2} + dMob_dS[ip][k_up] = m_dMob[seri[k_up]][sesri[k_up]][sei[k_up]][ip][Deriv::dS]; // dM/dS = {dM/dS1 , 0} OR {0 , dM/dS2} } else // perform smoothing { real64 const mobWeights[2] = { alpha, 1.0 - alpha }; for( integer ke = 0; ke < 2; ++ke ) { - mobility[ip] += mobWeights[ke] * m_mob[seri[ke]][sesri[ke]][sei[ke]][0][ip]; // M = alpha * M1 + (1 - alpha) * M2 - dMob_dP[ip][ke] = mobWeights[ke] * m_dMob[seri[ke]][sesri[ke]][sei[ke]][0][ip][Deriv::dP]; // dM/dP = {alpha * dM1/dP1 , (1 - alpha) * dM2/dP2} - dMob_dS[ip][ke] = mobWeights[ke] * m_dMob[seri[ke]][sesri[ke]][sei[ke]][0][ip][Deriv::dS]; // dM/dP = {alpha * dM1/dS1 , (1 - alpha) * dM2/dS2} + mobility[ip] += mobWeights[ke] * m_mob[seri[ke]][sesri[ke]][sei[ke]][ip]; // M = alpha * M1 + (1 - alpha) * M2 + dMob_dP[ip][ke] = mobWeights[ke] * m_dMob[seri[ke]][sesri[ke]][sei[ke]][ip][Deriv::dP]; // dM/dP = {alpha * dM1/dP1 , (1 - alpha) * dM2/dP2} + dMob_dS[ip][ke] = mobWeights[ke] * m_dMob[seri[ke]][sesri[ke]][sei[ke]][ip][Deriv::dS]; // dM/dP = {alpha * dM1/dS1 , (1 - alpha) * dM2/dS2} } } @@ -585,7 +590,7 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase * @param[in] iconn the connection index * @param[inout] stack the stack variables */ - template< typename FUNC = singlePhaseBaseKernels::NoOpFunc > // should change to multiphase + template< typename FUNC = singlePhaseBaseKernels::NoOpFunc > // should change to multiphase GEOS_HOST_DEVICE void complete( localIndex const iconn, StackVariables & stack, @@ -703,12 +708,13 @@ class FaceBasedAssemblyKernelFactory dofNumberAccessor.setName( solverName + "/accessors/" + dofKey ); using kernelType = FaceBasedAssemblyKernel< NUM_EQN, NUM_DOF, STENCILWRAPPER >; - typename kernelType::ImmiscibleMultiPhaseFlowAccessors flowAccessors( elemManager, solverName ); + typename kernelType::ImmiscibleMultiphaseFlowAccessors flowAccessors( elemManager, solverName ); + typename kernelType::MultiphaseFluidAccessors fluidAccessors( elemManager, solverName ); typename kernelType::CapPressureAccessors capPressureAccessors( elemManager, solverName ); typename kernelType::PermeabilityAccessors permAccessors( elemManager, solverName ); kernelType kernel( numPhases, rankOffset, stencilWrapper, dofNumberAccessor, - flowAccessors, capPressureAccessors, permAccessors, + flowAccessors, fluidAccessors, capPressureAccessors, permAccessors, dt, localMatrix, localRhs, hasCapPressure, useTotalMassEquation ); kernelType::template launch< POLICY >( stencilWrapper.size(), kernel ); } @@ -726,7 +732,7 @@ class PhaseMobilityKernel { public: - //using Base = isothermalCompositionalMultiphaseBaseKernels::PropertyKernelBase< NUM_COMP >; + //using Base = MultiphaseFluidAccessors::PropertyKernelBase< NUM_COMP >; /// Compile time value for the number of phases static constexpr integer numPhase = NUM_PHASE; @@ -786,10 +792,10 @@ class PhaseMobilityKernel for( integer ip = 0; ip < numPhase; ++ip ) { - real64 const density = m_phaseDens[ei][0][ip]; - real64 const dDens_dP = m_dPhaseDens[ei][0][ip]; - real64 const viscosity = m_phaseVisc[ei][0][ip]; - real64 const dVisc_dP = m_dPhaseVisc[ei][0][ip]; + real64 const density = m_phaseDens[ei][ip]; + real64 const dDens_dP = m_dPhaseDens[ei][ip]; + real64 const viscosity = m_phaseVisc[ei][ip]; + real64 const dVisc_dP = m_dPhaseVisc[ei][ip]; real64 const relPerm = m_phaseRelPerm[ei][0][ip]; @@ -800,7 +806,7 @@ class PhaseMobilityKernel for( integer jp = 0; jp < numPhase; ++jp ) // check if we need numPhase or numPhase-1 derivatives { - real64 const dRelPerm_dS = dPhaseRelPerm_dPhaseVolFrac[ei][0][ip][jp]; + real64 const dRelPerm_dS = m_dPhaseRelPerm_dPhaseVolFrac[ei][0][ip][jp]; dPhaseMob[ip][Deriv::dS+jp] = dRelPerm_dS * density / viscosity; } From 2d4f8971d222d8b0dbf377172ab1789a96a27d47 Mon Sep 17 00:00:00 2001 From: Ammara-14 Date: Wed, 21 Aug 2024 17:37:55 -0700 Subject: [PATCH 023/102] made minor fixes to make the code compile in release mode - thanks to Bertrand Denel for pointing them out --- .../physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp index 9d3594d71f8..9ccee0eabe0 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp @@ -501,7 +501,7 @@ void ImmiscibleMultiphaseFlow::assembleSystem( real64 const GEOS_UNUSED_PARAM( t CRSMatrixView< real64, globalIndex const > const & localMatrix, arrayView1d< real64 > const & localRhs ) { - GEOS_MARK_FUNCTION; // TODO Ralph + GEOS_MARK_FUNCTION; assembleAccumulationTerm( domain, dofManager, @@ -517,7 +517,7 @@ void ImmiscibleMultiphaseFlow::assembleSystem( real64 const GEOS_UNUSED_PARAM( t } -// This part of the code "assembleAccumulationTerm" is added by Ammar along with the comments. + void ImmiscibleMultiphaseFlow::assembleAccumulationTerm( DomainPartition & domain, DofManager const & dofManager, @@ -560,7 +560,7 @@ void ImmiscibleMultiphaseFlow::assembleAccumulationTerm( DomainPartition & domai // The line below is to be used if we want to use the total mass flux formulation //BitFlags< ElementBasedAssemblyKernelFlags > m_kernelFlags = kernelFlags; - GEOS_MARK_FUNCTION; + integer const numElems = subRegion.size(); forAll< parallelDevicePolicy<> >( @@ -620,7 +620,7 @@ void ImmiscibleMultiphaseFlow::assembleAccumulationTerm( DomainPartition & domai // complete - integer const numRows = numofPhases + 1; + integer const numRows = numofPhases; for( integer i = 0; i < numRows; ++i ) { From 3ecbf3d9cc2fb3119a764f805051ad7f6fcb0425 Mon Sep 17 00:00:00 2001 From: DENEL Bertrand Date: Mon, 16 Sep 2024 19:44:53 -0500 Subject: [PATCH 024/102] Added first version of a simplified two phase fluid model --- .../constitutive/CMakeLists.txt | 3 + .../fluid/twophasefluid/TwoPhaseFluid.cpp | 299 +++++++++++++++ .../fluid/twophasefluid/TwoPhaseFluid.hpp | 353 ++++++++++++++++++ .../twophasefluid/TwoPhaseFluidFields.hpp | 84 +++++ .../constitutiveTests/CMakeLists.txt | 5 +- .../constitutiveTests/testTwoPhaseFluid.cpp | 287 ++++++++++++++ 6 files changed, 1029 insertions(+), 2 deletions(-) create mode 100644 src/coreComponents/constitutive/fluid/twophasefluid/TwoPhaseFluid.cpp create mode 100644 src/coreComponents/constitutive/fluid/twophasefluid/TwoPhaseFluid.hpp create mode 100644 src/coreComponents/constitutive/fluid/twophasefluid/TwoPhaseFluidFields.hpp create mode 100644 src/coreComponents/unitTests/constitutiveTests/testTwoPhaseFluid.cpp diff --git a/src/coreComponents/constitutive/CMakeLists.txt b/src/coreComponents/constitutive/CMakeLists.txt index cae2dbc2e7f..79a03c56b53 100644 --- a/src/coreComponents/constitutive/CMakeLists.txt +++ b/src/coreComponents/constitutive/CMakeLists.txt @@ -102,6 +102,8 @@ set( constitutive_headers fluid/singlefluid/SingleFluidSelector.hpp fluid/singlefluid/SlurryFluidSelector.hpp fluid/singlefluid/ThermalCompressibleSinglePhaseFluid.hpp + fluid/twophasefluid/TwoPhaseFluid.hpp + fluid/twophasefluid/TwoPhaseFluidFields.hpp permeability/CarmanKozenyPermeability.hpp permeability/ConstantPermeability.hpp permeability/ExponentialDecayPermeability.hpp @@ -243,6 +245,7 @@ set( constitutive_sources fluid/singlefluid/SingleFluidBase.cpp fluid/singlefluid/SlurryFluidBase.cpp fluid/singlefluid/ThermalCompressibleSinglePhaseFluid.cpp + fluid/twophasefluid/TwoPhaseFluid.cpp permeability/CarmanKozenyPermeability.cpp permeability/ConstantPermeability.cpp permeability/ExponentialDecayPermeability.cpp diff --git a/src/coreComponents/constitutive/fluid/twophasefluid/TwoPhaseFluid.cpp b/src/coreComponents/constitutive/fluid/twophasefluid/TwoPhaseFluid.cpp new file mode 100644 index 00000000000..56325f2ef12 --- /dev/null +++ b/src/coreComponents/constitutive/fluid/twophasefluid/TwoPhaseFluid.cpp @@ -0,0 +1,299 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * SPDX-License-Identifier: LGPL-2.1-only + * + * Copyright (c) 2016-2024 Lawrence Livermore National Security LLC + * Copyright (c) 2018-2024 Total, S.A + * Copyright (c) 2018-2024 The Board of Trustees of the Leland Stanford Junior University + * Copyright (c) 2018-2024 Chevron + * Copyright (c) 2019- GEOS/GEOSX Contributors + * All rights reserved + * + * See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details. + * ------------------------------------------------------------------------------------------------------------ + */ + +/** + * @file TwoPhaseFluid.cpp + */ + +#include "TwoPhaseFluid.hpp" +#include "TwoPhaseFluidFields.hpp" + +#include "functions/FunctionManager.hpp" + + +namespace geos +{ + +using namespace dataRepository; + +namespace constitutive +{ + + +TwoPhaseFluid::TwoPhaseFluid( string const & name, Group * const parent ) + : ConstitutiveBase( name, parent ) +{ + registerWrapper( viewKeyStruct::phaseNamesString(), &m_phaseNames ). + setRTTypeName( rtTypes::CustomTypes::groupNameRefArray ). + setInputFlag( InputFlags::OPTIONAL ). + setDescription( "List of fluid phases" ); + + // 1) First option: specify PVT tables from one file per phase, read the files line by line, and populate the internal TableFunctions + registerWrapper( viewKeyStruct::tableFilesString(), &m_tableFiles ). + setInputFlag( InputFlags::OPTIONAL ). + setRestartFlags( RestartFlags::NO_WRITE ). + setDescription( "List of filenames with input PVT tables (one per phase)" ); + + // 2) Second option: specify TableFunction names for each phase, + registerWrapper( viewKeyStruct::densityTableNamesString(), &m_densityTableNames ). + setRTTypeName( rtTypes::CustomTypes::groupNameRefArray ). + setInputFlag( InputFlags::OPTIONAL ). + setDescription( "List of density TableFuncion names from the Function block. \n" + "The user must provide one TableFunction par phase, respecting the order provided in \"phaseNames\"." ); + + registerWrapper( viewKeyStruct::viscosityTableNamesString(), &m_viscosityTableNames ). + setRTTypeName( rtTypes::CustomTypes::groupNameRefArray ). + setInputFlag( InputFlags::OPTIONAL ). + setDescription( "List of viscosity TableFuncion names from the Function block. \n" + "The user must provide one TableFunction par phase, respecting the order provided in \"phaseNames\"." ); + + registerField( fields::twophasefluid::phaseDensity{}, &m_phaseDensity.value ); + registerField( fields::twophasefluid::dPhaseDensity{}, &m_phaseDensity.derivs ); + registerField( fields::twophasefluid::phaseDensity_n{}, &m_phaseDensity_n ); + + registerField( fields::twophasefluid::phaseViscosity{}, &m_phaseViscosity.value ); + registerField( fields::twophasefluid::dPhaseViscosity{}, &m_phaseViscosity.derivs ); +} + + +std::unique_ptr< ConstitutiveBase > +TwoPhaseFluid::deliverClone( string const & name, Group * const parent ) const +{ + return ConstitutiveBase::deliverClone( name, parent ); +} + + +void TwoPhaseFluid::resizeFields( localIndex const size, localIndex const numPts ) +{ + // Assume sole dependency on pressure, i.e. one derivative + m_phaseDensity.value.resize( size, numPts, 2 ); + m_phaseDensity.derivs.resize( size, numPts, 2, 1 ); + + m_phaseDensity_n.resize( size, numPts, 2 ); + + m_phaseViscosity.value.resize( size, numPts, 2 ); + m_phaseViscosity.derivs.resize( size, numPts, 2, 1 ); +} + + +void TwoPhaseFluid::allocateConstitutiveData( dataRepository::Group & parent, + localIndex const numConstitutivePointsPerParentIndex ) +{ + ConstitutiveBase::allocateConstitutiveData( parent, numConstitutivePointsPerParentIndex ); + resizeFields( parent.size(), numConstitutivePointsPerParentIndex ); +} + + +void TwoPhaseFluid::postInputInitialization() +{ + ConstitutiveBase::postInputInitialization(); + + // Input relationships can be provided either as text files or TableFunctions. + m_tableFiles.empty() ? readInputDataFromTableFunctions() : readInputDataFromFileTableFunctions(); + + + /* ??????? + // call to correctly set member array tertiary sizes on the 'main' material object + resizeFields( 0, 0 ); + + // set labels on array wrappers for plottable fields + setLabels(); + */ +} + + +void +TwoPhaseFluid::readTable( string const & fileName, + integer minRowLength, + array1d< array1d< real64 > > & data ) +{ + std::ifstream is( fileName ); + GEOS_ERROR_IF( !is.is_open(), + "TwoPhaseFluid: could not open file: " << fileName ); + + // Read line-by-line until eof + string str; + while( std::getline( is, str ) ) + { + // Remove whitespace and end-of-line characters, if any + str = stringutilities::trim( str, " \r" ); + + // Remove # and -- (Eclipse-style) comments + str = stringutilities::removeStringAndFollowingContent( str, "#" ); + str = stringutilities::removeStringAndFollowingContent( str, "--" ); + + // Skip empty or comment-only strings + if( str.empty() ) + continue; + + // Add and read a new line entry + array1d< real64 > newLine = stringutilities::fromStringToArray< real64 >( str ); + if( !newLine.empty() ) + { + data.emplace_back( std::move( newLine ) ); + } + } + + is.close(); + + for( localIndex i = 0; i < data.size(); ++i ) + { + GEOS_ERROR_IF( data[i].size() < minRowLength, + "TwoPhaseFluid: too few entries in row " << i << " of table " << fileName + << ", minimum " << std::to_string( minRowLength ) << " required" ); + } +} + + +void TwoPhaseFluid::fillData( integer const ip, + array1d< array1d< real64 > > const & tableValues ) +{ + array1d< array1d< real64 > > pressureCoords( 1 ); + pressureCoords[0].resize( tableValues.size() ); + array1d< real64 > density( tableValues.size() ); + array1d< real64 > viscosity( tableValues.size() ); + + for( localIndex i = 0; i < tableValues.size(); ++i ) + { + GEOS_THROW_IF_NE_MSG( tableValues[i].size(), 3, + getFullName() << ": three columns (pressure, density, and viscosity) are expected", + InputError ); + + pressureCoords[0][i] = tableValues[i][0]; + density[i] = tableValues[i][1]; + viscosity[i] = tableValues[i][2]; + } + + string const densityTableName = getName() + "DensityPhase" + GEOS_FMT( "{}", ip ); + string const viscosityTableName = getName() + "ViscosityPhase" + GEOS_FMT( "{}", ip ); + m_densityTableNames.emplace_back( densityTableName ); + m_viscosityTableNames.emplace_back( viscosityTableName ); + + FunctionManager & functionManager = FunctionManager::getInstance(); + + TableFunction & tableDensity = + dynamicCast< TableFunction & >( *functionManager.createChild( "TableFunction", densityTableName ) ); + tableDensity.setTableCoordinates( pressureCoords, { units::Pressure } ); + tableDensity.setTableValues( density, units::Density ); + tableDensity.setInterpolationMethod( TableFunction::InterpolationType::Linear ); + + TableFunction & tableViscosity = + dynamicCast< TableFunction & >( *functionManager.createChild( "TableFunction", viscosityTableName ) ); + tableViscosity.setTableCoordinates( pressureCoords, { units::Pressure } ); + tableViscosity.setTableValues( viscosity, units::Viscosity ); + tableViscosity.setInterpolationMethod( TableFunction::InterpolationType::Linear ); +} + + +void TwoPhaseFluid::readInputDataFromFileTableFunctions() +{ + // Check for ambiguous definition + GEOS_THROW_IF( !(m_densityTableNames.empty() && m_viscosityTableNames.empty()), + GEOS_FMT( "{}: input is redundant (both TableFunction names and text files)", getFullName() ), + InputError ); + + + // Check that we have exactly two table files (one per phase) + GEOS_THROW_IF_NE_MSG( m_tableFiles.size(), 2, + GEOS_FMT( "{}: expecting two table files (one per phase)", getFullName() ), + InputError ); + + array1d< array1d< real64 > > tableValues; + for( integer ip = 0; ip < 2; ++ip ) + { + tableValues.clear(); + readTable( m_tableFiles[ip], 3, tableValues ); + fillData( ip, tableValues ); + } +} + + +void TwoPhaseFluid::readInputDataFromTableFunctions() +{ + // Check for ambiguous definition + GEOS_THROW_IF( !m_tableFiles.empty(), + GEOS_FMT( "{}: input is redundant (both TableFunction names and text files)", getFullName() ), + InputError ); + + // Since we are considering a two phase fluid, we should have exactly 2 tables per property + GEOS_THROW_IF_NE_MSG( m_densityTableNames.size(), 2, + GEOS_FMT( "{}: one density table must be provided for each phase", getFullName() ), + InputError ); + + GEOS_THROW_IF_NE_MSG( m_viscosityTableNames.size(), 2, + GEOS_FMT( "{}: one viscosity table must be provided for each phase", getFullName() ), + InputError ); + + + FunctionManager const & functionManager = FunctionManager::getInstance(); + + for( integer iph = 0; iph < 2; ++iph ) + { + GEOS_THROW_IF( !functionManager.hasGroup( m_densityTableNames[iph] ), + GEOS_FMT( "{}: density table '{}' not found", getFullName(), m_densityTableNames[iph] ), + InputError ); + + GEOS_THROW_IF( !functionManager.hasGroup( m_viscosityTableNames[iph] ), + GEOS_FMT( "{}: viscosity table '{}' not found", getFullName(), m_viscosityTableNames[iph] ), + InputError ); + } +} + + +void TwoPhaseFluid::initializePostSubGroups() +{ + ConstitutiveBase::initializePostSubGroups(); + + FunctionManager const & functionManager = FunctionManager::getInstance(); + for( integer iph = 0; iph < 2; ++iph ) + { + // Grab the tables by name from the function manager, + // then add them in a list to create their table wrappers when needed + TableFunction const & densityTable = functionManager.getGroup< TableFunction const >( m_densityTableNames[iph] ); + m_densityTables.emplace_back( &densityTable ); + m_densityTableKernels.emplace_back( m_densityTables[iph]->createKernelWrapper() ); + + TableFunction const & viscosityTable = functionManager.getGroup< TableFunction const >( m_viscosityTableNames[iph] ); + m_viscosityTables.emplace_back( &viscosityTable ); + m_viscosityTableKernels.emplace_back( m_viscosityTables[iph]->createKernelWrapper() ); + } +} + + +TwoPhaseFluid::KernelWrapper +TwoPhaseFluid::createKernelWrapper() +{ + return KernelWrapper( m_densityTableKernels, + m_viscosityTableKernels, + m_phaseDensity.toView(), + m_phaseViscosity.toView()); +} + + +TwoPhaseFluid::KernelWrapper::KernelWrapper( + arrayView1d< TableFunction::KernelWrapper const > densityTables, + arrayView1d< TableFunction::KernelWrapper const > viscosityTables, + PhaseProp::ViewType phaseDensity, + PhaseProp::ViewType phaseViscosity ) + : m_densityTables( std::move( densityTables )), + m_viscosityTables( std::move( viscosityTables )), + m_phaseDensity( std::move( phaseDensity )), + m_phaseViscosity( std::move( phaseViscosity )) {} + + +REGISTER_CATALOG_ENTRY( ConstitutiveBase, TwoPhaseFluid, string const &, Group * const ) + +} // namespace constitutive +} // namespace geos diff --git a/src/coreComponents/constitutive/fluid/twophasefluid/TwoPhaseFluid.hpp b/src/coreComponents/constitutive/fluid/twophasefluid/TwoPhaseFluid.hpp new file mode 100644 index 00000000000..f870ac0c73e --- /dev/null +++ b/src/coreComponents/constitutive/fluid/twophasefluid/TwoPhaseFluid.hpp @@ -0,0 +1,353 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * SPDX-License-Identifier: LGPL-2.1-only + * + * Copyright (c) 2016-2024 Lawrence Livermore National Security LLC + * Copyright (c) 2018-2024 Total, S.A + * Copyright (c) 2018-2024 The Board of Trustees of the Leland Stanford Junior University + * Copyright (c) 2018-2024 Chevron + * Copyright (c) 2019- GEOS/GEOSX Contributors + * All rights reserved + * + * See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details. + * ------------------------------------------------------------------------------------------------------------ + */ + +/** + * @file TwoPhaseFluid.hpp + */ + +#ifndef GEOS_CONSTITUTIVE_FLUID_TWOPHASEFLUID_TWOPHASEFLUID_HPP_ +#define GEOS_CONSTITUTIVE_FLUID_TWOPHASEFLUID_TWOPHASEFLUID_HPP_ + +#include "common/DataLayouts.hpp" +#include "functions/TableFunction.hpp" +#include "constitutive/ConstitutiveBase.hpp" + +#include "constitutive/fluid/multifluid/Layouts.hpp" +#include "constitutive/fluid/multifluid/MultiFluidUtils.hpp" + +#include "constitutive/ConstitutivePassThruHandler.hpp" + + +namespace geos +{ +namespace constitutive +{ + +class TwoPhaseFluid : public ConstitutiveBase +{ +public: + + TwoPhaseFluid( string const & name, + Group * const parent ); + + virtual std::unique_ptr< ConstitutiveBase > + deliverClone( string const & name, + Group * const parent ) const override; + + virtual void allocateConstitutiveData( dataRepository::Group & parent, + localIndex const numConstitutivePointsPerParentIndex ) override; + + /** + * @name Static Factory Catalog members and functions + */ + ///@{ + + /// string name to use for this class in the catalog + static constexpr auto m_catalogNameString = "TwoPhaseFluid"; + + /** + * @brief Static catalog string + * @return A string that is used to register/lookup this class in the registry + */ + static std::string catalogName() { return m_catalogNameString; } + + /** + * @brief Get catalog name + * @return Name string + */ + virtual string getCatalogName() const override { return catalogName(); } + + ///@} + + + + /** + * @brief Getter for the fluid phase names + * @return an array storing the phase names + */ + arrayView1d< string const > phaseNames() const { return m_phaseNames; } + + struct viewKeyStruct : ConstitutiveBase::viewKeyStruct + { + static constexpr char const * tableFilesString() { return "tableFiles"; } + static constexpr char const * phaseNamesString() { return "phaseNames"; } + static constexpr char const * densityTableNamesString() { return "densityTableNames"; } + static constexpr char const * viscosityTableNamesString() { return "viscosityTableNames"; } + }; + + arrayView3d< real64 const, multifluid::USD_PHASE > phaseDensity_n() const + { return m_phaseDensity_n; } + + arrayView3d< real64 const, multifluid::USD_PHASE > phaseDensity() const + { return m_phaseDensity.value; } + + arrayView4d< real64 const, multifluid::USD_PHASE_DC > dPhaseDensity() const + { return m_phaseDensity.derivs; } + + arrayView3d< real64 const, multifluid::USD_PHASE > phaseViscosity() const + { return m_phaseViscosity.value; } + + arrayView4d< real64 const, multifluid::USD_PHASE_DC > dPhaseViscosity() const + { return m_phaseViscosity.derivs; } + + using PhaseProp = MultiFluidVar< real64, 3, constitutive::multifluid::LAYOUT_PHASE, constitutive::multifluid::LAYOUT_PHASE_DC >; + + + class KernelWrapper + { +public: + + /// @cond DO_NOT_DOCUMENT + /// We need these SMFs to avoid host-device errors with CUDA. + KernelWrapper() = default; + KernelWrapper( KernelWrapper const & ) = default; + KernelWrapper & operator=( KernelWrapper const & ) = default; + KernelWrapper & operator=( KernelWrapper && ) = default; + /// @endcond + + /** + * @brief Get number of elements in this wrapper. + * @return number of elements + */ + GEOS_HOST_DEVICE + GEOS_FORCE_INLINE + localIndex numElems() const { return m_phaseDensity.value.size( 0 ); } + + /** + * @brief Get number of gauss points per element. + * @return number of gauss points per element + */ + GEOS_HOST_DEVICE + GEOS_FORCE_INLINE + localIndex numGauss() const { return m_phaseDensity.value.size( 1 ); } + + + GEOS_HOST_DEVICE + void compute( real64 const pressure, + PhaseProp::SliceType const phaseDensity, + PhaseProp::SliceType const phaseViscosity ) const; + + GEOS_HOST_DEVICE + void update( localIndex const k, + localIndex const q, + real64 const pressure ) const; + +private: + + friend class TwoPhaseFluid; + + /** + * @brief Constructor for the class doing in-kernel two-phase fluid updates + * @param[in] densityTables density tables + * @param[in] viscosityTables viscosity tables + * @param[in] phaseDensity phase densities (+ derivatives) in the cell + * @param[in] phaseViscosity phase viscosities (+ derivatives) in the cell + */ + KernelWrapper( + arrayView1d< TableFunction::KernelWrapper const > densityTables, + arrayView1d< TableFunction::KernelWrapper const > viscosityTables, + PhaseProp::ViewType phaseDensity, + PhaseProp::ViewType phaseViscosity ); + + +protected: + + KernelWrapper( + arrayView1d< TableFunction::KernelWrapper const > densityTables, + arrayView1d< TableFunction::KernelWrapper const > viscosityTables + ); + + /// Table kernel wrappers to interpolate in the two phase (\rho vs p) tables + arrayView1d< TableFunction::KernelWrapper const > m_densityTables; + + /// Table kernel wrappers to interpolate in the two phase (\mu vs p) tables + arrayView1d< TableFunction::KernelWrapper const > m_viscosityTables; + + /** + * @brief Utility function to compute densities as a function of pressure (keeping derivatives) + * @param[in] pressure pressure in the cell + * @param[out] phaseDensity the phase density in the cell (+ derivatives) + */ + GEOS_HOST_DEVICE + void computeDensities( real64 const pressure, + PhaseProp::SliceType const & phaseDensity ) const; + + /** + * @brief Utility function to compute viscosities as a function of pressure (keeping derivatives) + * @param[in] pressure pressure in the cell + * @param[out] phaseViscosity the phase viscosities in the cell (+ derivatives) + */ + GEOS_HOST_DEVICE + void computeViscosities( real64 const pressure, + PhaseProp::SliceType const & phaseViscosity ) const; + + /// Views on the phase properties + PhaseProp::ViewType m_phaseDensity; + PhaseProp::ViewType m_phaseViscosity; + + }; //class KernelWrapper + + + array1d< string > m_phaseNames; + + + path_array m_tableFiles; + + /// Names of the density tables (one per phase) + array1d< string > m_densityTableNames; + + /// Names of the viscosity tables (one per phase) + array1d< string > m_viscosityTableNames; + + PhaseProp m_phaseDensity; + PhaseProp m_phaseViscosity; + + /// Backup data + array3d< real64, multifluid::LAYOUT_PHASE > m_phaseDensity_n; + + + virtual void resizeFields( localIndex const size, localIndex const numPts ); + + virtual void postInputInitialization() override; + + virtual void initializePostSubGroups() override; + + /// Table kernel wrappers to interpolate (\rho vs p) tables + array1d< TableFunction const * > m_densityTables; + /// Table kernel wrappers of m_densityTables + array1d< TableFunction::KernelWrapper > m_densityTableKernels; + + /// Table kernel wrappers to interpolate (\mu vs p) tables + array1d< TableFunction const * > m_viscosityTables; + /// Table kernel wrappers of m_viscosityTables + array1d< TableFunction::KernelWrapper > m_viscosityTableKernels; + + KernelWrapper createKernelWrapper(); + + +private: + void readInputDataFromTableFunctions(); + void readInputDataFromFileTableFunctions(); + + /** + * @brief Fill the fluid data (pressure, density, viscosity) + * @param[in] ip the index of the phase + * @param[in] tableValues the values in the fluid table + */ + void fillData( integer const ip, + array1d< array1d< real64 > > const & tableValues ); + + /** + * @brief Read a table from file and check its row length + * @param[in] fileName the name of the file + * @param[in] minRowLength the expected minimum row length (typically 3: pressure, density, viscosity) + * @param[out] data the data from the table + */ + static void + readTable( string const & fileName, + integer minRowLength, + array1d< array1d< real64 > > & data ); +}; + + +GEOS_HOST_DEVICE +GEOS_FORCE_INLINE +void TwoPhaseFluid::KernelWrapper:: + computeDensities( real64 const pressure, + PhaseProp::SliceType const & phaseDensity ) const +{ + using Deriv = constitutive::multifluid::DerivativeOffset; + + LvArray::forValuesInSlice( phaseDensity.derivs, []( real64 & val ) { val = 0.0; } ); + + for( integer iph = 0; iph < 2; ++iph ) + { + // interpolate in the table to get the phase density and derivatives + real64 dPhaseDens_dPres = 0.0; + + phaseDensity.value[iph] = m_densityTables[iph].compute( &pressure, &dPhaseDens_dPres ); + phaseDensity.derivs[iph][Deriv::dP] = dPhaseDens_dPres; + } +} + + +GEOS_HOST_DEVICE +GEOS_FORCE_INLINE +void TwoPhaseFluid::KernelWrapper:: + computeViscosities( real64 const pressure, + PhaseProp::SliceType const & phaseViscosity ) const +{ + using Deriv = constitutive::multifluid::DerivativeOffset; + + LvArray::forValuesInSlice( phaseViscosity.derivs, []( real64 & val ) { val = 0.0; } ); + + for( integer iph = 0; iph < 2; ++iph ) + { + // interpolate in the table to get the phase viscosity and derivatives + real64 dPhaseVisc_dPres = 0.0; + phaseViscosity.value[iph] = m_viscosityTables[iph].compute( &pressure, &dPhaseVisc_dPres ); + phaseViscosity.derivs[iph][Deriv::dP] = dPhaseVisc_dPres; + } +} + + +GEOS_HOST_DEVICE +GEOS_FORCE_INLINE +void TwoPhaseFluid::KernelWrapper:: + compute( real64 const pressure, + PhaseProp::SliceType const phaseDensity, + PhaseProp::SliceType const phaseViscosity ) const +{ + computeDensities( pressure, + phaseDensity ); + + computeViscosities( pressure, + phaseViscosity ); +} + + +GEOS_HOST_DEVICE +GEOS_FORCE_INLINE +void TwoPhaseFluid::KernelWrapper:: + update( localIndex const k, + localIndex const q, + real64 const pressure + ) const +{ + compute( pressure, + m_phaseDensity( k, q ), + m_phaseViscosity( k, q ) ); +} + + +template< typename LAMBDA > +void constitutiveUpdatePassThru( TwoPhaseFluid const & fluid, + LAMBDA && lambda ) +{ + ConstitutivePassThruHandler< TwoPhaseFluid >::execute( fluid, std::forward< LAMBDA >( lambda ) ); +} + + +template< typename LAMBDA > +void constitutiveUpdatePassThru( TwoPhaseFluid & fluid, + LAMBDA && lambda ) +{ + ConstitutivePassThruHandler< TwoPhaseFluid >::execute( fluid, std::forward< LAMBDA >( lambda ) ); +} + +} // namespace constitutive +} // namespace geos + +#endif // GEOS_CONSTITUTIVE_FLUID_TWOPHASEFLUID_TWOPHASEFLUID_HPP_ diff --git a/src/coreComponents/constitutive/fluid/twophasefluid/TwoPhaseFluidFields.hpp b/src/coreComponents/constitutive/fluid/twophasefluid/TwoPhaseFluidFields.hpp new file mode 100644 index 00000000000..9191deebd5d --- /dev/null +++ b/src/coreComponents/constitutive/fluid/twophasefluid/TwoPhaseFluidFields.hpp @@ -0,0 +1,84 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * SPDX-License-Identifier: LGPL-2.1-only + * + * Copyright (c) 2016-2024 Lawrence Livermore National Security LLC + * Copyright (c) 2018-2024 Total, S.A + * Copyright (c) 2018-2024 The Board of Trustees of the Leland Stanford Junior University + * Copyright (c) 2018-2024 Chevron + * Copyright (c) 2019- GEOS/GEOSX Contributors + * All rights reserved + * + * See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details. + * ------------------------------------------------------------------------------------------------------------ + */ + +/** + * @file TwoPhaseFluidFields.hpp + */ + +#ifndef GEOS_CONSTITUTIVE_FLUID_TWOPHASEFLUIDFIELDS_HPP_ +#define GEOS_CONSTITUTIVE_FLUID_TWOPHASEFLUIDFIELDS_HPP_ + +#include "constitutive/fluid/multifluid/Layouts.hpp" +#include "mesh/MeshFields.hpp" + + +namespace geos +{ + +namespace fields +{ + +namespace twophasefluid +{ + +using array3dLayoutPhase = array3d< real64, constitutive::multifluid::LAYOUT_PHASE >; +using array4dLayoutPhase_d = array4d< real64, constitutive::multifluid::LAYOUT_PHASE_DC >; + +DECLARE_FIELD( phaseDensity, + "phaseDensity", + array3dLayoutPhase, + 0, + LEVEL_0, + WRITE_AND_READ, + "Phase density" ); + +DECLARE_FIELD( phaseDensity_n, + "phaseDensity_n", + array3dLayoutPhase, + 0, + NOPLOT, + WRITE_AND_READ, + "Phase density at the previous converged time step" ); + +DECLARE_FIELD( dPhaseDensity, + "dPhaseDensity", + array4dLayoutPhase_d, + 0, + NOPLOT, + NO_WRITE, + "Derivative of phase density with respect to pressure" ); + +DECLARE_FIELD( phaseViscosity, + "phaseViscosity", + array3dLayoutPhase, + 0, + LEVEL_0, + WRITE_AND_READ, + "Phase viscosity" ); + +DECLARE_FIELD( dPhaseViscosity, + "dPhaseViscosity", + array4dLayoutPhase_d, + 0, + NOPLOT, + NO_WRITE, + "Derivative of phase viscosity with respect to pressure" ); + +} // namespace twophasefluid + +} // namespace constitutive +} // namespace geos + +#endif // GEOS_CONSTITUTIVE_FLUID_TWOPHASEFLUIDFIELDS_HPP_ diff --git a/src/coreComponents/unitTests/constitutiveTests/CMakeLists.txt b/src/coreComponents/unitTests/constitutiveTests/CMakeLists.txt index 24fb4d17cef..46bbeba7853 100644 --- a/src/coreComponents/unitTests/constitutiveTests/CMakeLists.txt +++ b/src/coreComponents/unitTests/constitutiveTests/CMakeLists.txt @@ -8,7 +8,8 @@ set( gtest_geosx_tests testMultiFluidDeadOil.cpp testMultiFluidLiveOil.cpp testRelPerm.cpp - testRelPermHysteresis.cpp ) + testRelPermHysteresis.cpp + testTwoPhaseFluid.cpp ) set( gtest_triaxial_xmls testTriaxial_druckerPragerExtended.xml @@ -110,4 +111,4 @@ foreach(test ${gtest_reactivefluid_xmls}) get_filename_component( test_name ${test} NAME_WE ) geos_add_test( NAME ${test_name} COMMAND testReactiveFluid -i ${CMAKE_CURRENT_LIST_DIR}/${test} ) -endforeach() \ No newline at end of file +endforeach() diff --git a/src/coreComponents/unitTests/constitutiveTests/testTwoPhaseFluid.cpp b/src/coreComponents/unitTests/constitutiveTests/testTwoPhaseFluid.cpp new file mode 100644 index 00000000000..b25c569b5d4 --- /dev/null +++ b/src/coreComponents/unitTests/constitutiveTests/testTwoPhaseFluid.cpp @@ -0,0 +1,287 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * SPDX-License-Identifier: LGPL-2.1-only + * + * Copyright (c) 2016-2024 Lawrence Livermore National Security LLC + * Copyright (c) 2018-2024 Total, S.A + * Copyright (c) 2018-2024 The Board of Trustees of the Leland Stanford Junior University + * Copyright (c) 2018-2024 Chevron + * Copyright (c) 2019- GEOS/GEOSX Contributors + * All rights reserved + * + * See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details. + * ------------------------------------------------------------------------------------------------------------ + */ + +#include "mainInterface/GeosxState.hpp" +#include "mainInterface/initialization.hpp" + +#include "constitutive/fluid/twophasefluid/TwoPhaseFluid.hpp" +#include "constitutive/fluid/twophasefluid/TwoPhaseFluidFields.hpp" + +// Only for fill +#include "unitTests/constitutiveTests/MultiFluidTest.hpp" + +// Only for initializeTable +#include "unitTests/constitutiveTests/constitutiveTestHelpers.hpp" + + +using namespace geos; +using namespace geos::testing; +using namespace geos::constitutive; +using namespace geos::dataRepository; /// Only for group definition + + +static constexpr char const * tableContentPhase0 = "# Pg(Pa) Dens(kg/m3) Visc(Pa.s)\n" + "0.22 0.40203 40203\n" + "0.3 0.31311 31311\n" + "0.5 0.22423 22423\n" + "0.6 0.15011 15011\n" + "0.8 0.04224 4224\n" + "1.0 0.00603 603"; + +static constexpr char const * tableContentPhase1 = "# Pg(Pa) Dens(kg/m3) Visc(Pa.s)\n" + "1.22 0.40203 0.22\n" + "1.3 0.31311 0.22\n" + "1.5 0.22423 0.22\n" + "1.6 0.15011 0.22\n" + "1.8 0.04224 0.22\n" + "2.0 0.00603 0.22"; + +template< bool FROM_TABLE > +class TwoPhaseFluidTest : public ConstitutiveTestBase< TwoPhaseFluid > +{ +public: + + TwoPhaseFluidTest() + { + if constexpr (!FROM_TABLE) + { + writeTableToFile( "phase0.txt", tableContentPhase0 ); + writeTableToFile( "phase1.txt", tableContentPhase1 ); + } + + m_parent.resize( 1 ); + string const fluidName = GEOS_FMT( "fluid{}", (FROM_TABLE ? "Tables" : "Files")); + m_model = makeTwoPhaseFluid( fluidName, m_parent ); + + m_parent.initialize(); + m_parent.initializePostInitialConditions(); + } + + ~TwoPhaseFluidTest() + { + if constexpr (!FROM_TABLE) + { + removeFile( "phase0.txt" ); + removeFile( "phase1.txt" ); + } + } + + constitutive::TwoPhaseFluid & getFluid() const { return *m_model; } + + dataRepository::Group & getParent() { return m_parent; } + + + void testDerivatives( constitutive::TwoPhaseFluid & fluid, + dataRepository::Group * parent, + real64 const pressure, + real64 const perturbParameter, + real64 const relTol, + real64 const absTol = std::numeric_limits< real64 >::max() ) + { + auto const & phaseNames = fluid.getReference< string_array >( TwoPhaseFluid::viewKeyStruct::phaseNamesString() ); + + arrayView3d< real64 const, constitutive::multifluid::USD_PHASE > phaseDensity; + arrayView3d< real64 const, constitutive::multifluid::USD_PHASE > phaseViscosity; + arrayView4d< real64 const, constitutive::multifluid::USD_PHASE_DC > dPhaseDensity_dPressure; + arrayView4d< real64 const, constitutive::multifluid::USD_PHASE_DC > dPhaseViscosity_dPressure; + + // create a clone of the fluid to run updates on + string const fluidCopyName = fluid.getName() + "Copy"; + std::unique_ptr< constitutive::ConstitutiveBase > fluidCopyPtr = fluid.deliverClone( fluidCopyName, parent ); + constitutive::TwoPhaseFluid & fluidCopy = dynamicCast< constitutive::TwoPhaseFluid & >( *fluidCopyPtr ); + fluidCopy.initializePostSubGroups(); + + fluid.allocateConstitutiveData( fluid.getParent(), 1 ); + fluidCopy.allocateConstitutiveData( fluid.getParent(), 1 ); + + // extract data views from both fluids +#define GET_FLUID_DATA( FLUID, TRAIT ) \ + FLUID.getReference< TRAIT::type >( TRAIT::key() )[0][0] + + constitutive::MultiFluidVarSlice< real64, 1, constitutive::multifluid::USD_PHASE - 2, constitutive::multifluid::USD_PHASE_DC - 2 > phaseVisc { + GET_FLUID_DATA( fluid, fields::twophasefluid::phaseViscosity ), + GET_FLUID_DATA( fluid, fields::twophasefluid::dPhaseViscosity ) + }; + + constitutive::MultiFluidVarSlice< real64, 1, constitutive::multifluid::USD_PHASE - 2, constitutive::multifluid::USD_PHASE_DC - 2 > phaseDens { + GET_FLUID_DATA( fluid, fields::twophasefluid::phaseDensity ), + GET_FLUID_DATA( fluid, fields::twophasefluid::dPhaseDensity ) + }; + + auto const & phaseDensCopy = GET_FLUID_DATA( fluidCopy, fields::twophasefluid::phaseDensity ); + auto const & phaseViscCopy = GET_FLUID_DATA( fluidCopy, fields::twophasefluid::phaseViscosity ); +#undef GET_FLUID_DATA + + + // set the original fluid state to current + constitutive::constitutiveUpdatePassThru( fluid, [&] ( auto & castedFluid ) + { + typename TYPEOFREF( castedFluid ) ::KernelWrapper fluidWrapper = castedFluid.createKernelWrapper(); + fluidWrapper.update( 0, 0, pressure ); + } ); + + // now perturb variables and update the copied fluid's state + constitutive::constitutiveUpdatePassThru( fluidCopy, [&] ( auto & castedFluid ) + { + using Deriv = constitutive::multifluid::DerivativeOffset; + + typename TYPEOFREF( castedFluid ) ::KernelWrapper fluidWrapper = castedFluid.createKernelWrapper(); + + // to be able to use the checkDerivative utility function, we have to invert the layout + auto dPhaseDens = invertLayout( phaseDens.derivs.toSliceConst(), 2, 1 ); + auto dPhaseVisc = invertLayout( phaseVisc.derivs.toSliceConst(), 2, 1 ); + + // update pressure and check derivatives + real64 const dP = perturbParameter * (pressure + perturbParameter); + fluidWrapper.update( 0, 0, pressure + dP ); + + checkDerivative( phaseDensCopy.toSliceConst(), phaseDens.value.toSliceConst(), dPhaseDens[Deriv::dP].toSliceConst(), + dP, relTol, absTol, "phaseDens", "Pressure", phaseNames ); + checkDerivative( phaseViscCopy.toSliceConst(), phaseVisc.value.toSliceConst(), dPhaseVisc[Deriv::dP].toSliceConst(), + dP, relTol, absTol, "phaseVisc", "Pressure", phaseNames ); + } ); + } // void testDerivatives + + +protected: + static void writeTableToFile( string const & fileName, char const * content ) + { + std::ofstream os( fileName ); + ASSERT_TRUE( os.is_open() ); + os << content; + os.close(); + } + + static void removeFile( string const & fileName ) + { + int const ret = std::remove( fileName.c_str() ); + ASSERT_TRUE( ret == 0 ); + } + + +private: + static TwoPhaseFluid * makeTwoPhaseFluid( string const & name, Group & parent ); + +}; // class TwoPhaseFluidTest + + +template<> +TwoPhaseFluid * TwoPhaseFluidTest< true >::makeTwoPhaseFluid( string const & name, Group & parent ) +{ + // 1D table with linear interpolation + localIndex constexpr Naxis = 6; + localIndex constexpr NaxisSingle = 1; + + array1d< real64_array > densityCoordPhase0( 1 ); + fill< Naxis >( densityCoordPhase0[0], { 0.22, 0.3, 0.5, 0.6, 0.8, 1.0 } ); + real64_array densityValuesPhase0; + fill< Naxis >( densityValuesPhase0, { 0.40203, 0.31311, 0.22423, 0.15011, 0.04224, 0.00603 } ); + + array1d< real64_array > densityCoordPhase1( 1 ); + fill< Naxis >( densityCoordPhase1[0], { 1.22, 1.3, 1.5, 1.6, 1.8, 2.0 } ); + real64_array densityValuesPhase1; + fill< Naxis >( densityValuesPhase1, { 0.40203, 0.31311, 0.22423, 0.15011, 0.04224, 0.00603 } ); + + + array1d< real64_array > viscosityCoordPhase0( 1 ); + fill< Naxis >( viscosityCoordPhase0[0], { 0.22, 0.3, 0.5, 0.6, 0.8, 1.0 } ); + real64_array viscosityValuesPhase0; + fill< Naxis >( viscosityValuesPhase0, { 40203, 31311, 22423, 15011, 4224, 603 } ); + + array1d< real64_array > viscosityCoordPhase1( 1 ); + fill< NaxisSingle >( viscosityCoordPhase1[0], { 0.22 } ); + real64_array viscosityValuesPhase1; + fill< NaxisSingle >( viscosityValuesPhase1, { 45 } ); + + initializeTable( "densityTablePhase0", densityCoordPhase0, densityValuesPhase0 ); + initializeTable( "densityTablePhase1", densityCoordPhase1, densityValuesPhase1 ); + initializeTable( "viscosityTablePhase0", viscosityCoordPhase0, viscosityValuesPhase0 ); + initializeTable( "viscosityTablePhase1", viscosityCoordPhase1, viscosityValuesPhase1 ); + + + // 2) Set up the constitutive model + TwoPhaseFluid & fluid = parent.registerGroup< TwoPhaseFluid >( name ); + + string_array & phaseNames = fluid.getReference< string_array >( TwoPhaseFluid::viewKeyStruct::phaseNamesString() ); + fill< 2 >( phaseNames, {"oil", "water"} ); + + string_array & densityTableNames = fluid.getReference< string_array >( TwoPhaseFluid::viewKeyStruct::densityTableNamesString() ); + fill< 2 >( densityTableNames, {"densityTablePhase0", "densityTablePhase1"} ); + + string_array & viscosityTableNames = fluid.getReference< string_array >( TwoPhaseFluid::viewKeyStruct::viscosityTableNamesString() ); + fill< 2 >( viscosityTableNames, {"viscosityTablePhase0", "viscosityTablePhase1"} ); + + fluid.postInputInitializationRecursive(); + //fluid.initialize(); // to test all the checks???... this one is redoing the postInput + return &fluid; +} + + +template<> +TwoPhaseFluid * TwoPhaseFluidTest< false >::makeTwoPhaseFluid( string const & name, Group & parent ) +{ + TwoPhaseFluid & fluid = parent.registerGroup< TwoPhaseFluid >( name ); + + path_array & tableNames = fluid.getReference< path_array >( TwoPhaseFluid::viewKeyStruct::tableFilesString() ); + fill< 2 >( tableNames, {"phase0.txt", "phase1.txt"} ); + + fluid.postInputInitializationRecursive(); + return &fluid; +} + + + +using TwoPhaseFluidTestFromFiles = TwoPhaseFluidTest< false >; +using TwoPhaseFluidTestFromTables = TwoPhaseFluidTest< true >; + + +TEST_F( TwoPhaseFluidTestFromTables, testNumericalDerivative_initFromTables ) +{ + auto & fluid = getFluid(); + real64 constexpr eps = sqrt( std::numeric_limits< real64 >::epsilon()); + real64 constexpr relTol = 1.0e-8; + real64 constexpr absTol = 1.0e-8; + + for( real64 const pressure : { 0.55, 1.0, 10.0 } ) + { + testDerivatives( fluid, &getParent(), pressure, eps, relTol, absTol ); + } +} + + +TEST_F( TwoPhaseFluidTestFromFiles, testNumericalDerivative_initFromFiles ) +{ + auto & fluid = getFluid(); + real64 constexpr eps = sqrt( std::numeric_limits< real64 >::epsilon()); + real64 constexpr relTol = 1.0e-8; + real64 constexpr absTol = 1.0e-8; + + for( real64 const pressure : { 0.55, 1.0, 10.0 } ) + { + testDerivatives( fluid, &getParent(), pressure, eps, relTol, absTol ); + } +} + + +int main( int argc, char * * argv ) +{ + ::testing::InitGoogleTest( &argc, argv ); + + geos::GeosxState state( geos::basicSetup( argc, argv ) ); + int const result = RUN_ALL_TESTS(); + geos::basicCleanup(); + + return result; +} From 549629d6bd905cb8753062d746b4b388e9d824e7 Mon Sep 17 00:00:00 2001 From: DENEL Bertrand Date: Mon, 16 Sep 2024 20:09:50 -0500 Subject: [PATCH 025/102] Started modifications to use twoPhaseFluid model in the flow solver. --- .../fluidFlow/ImmiscibleMultiphaseFlow.cpp | 28 ++++++++++++++----- .../fluidFlow/ImmiscibleMultiphaseKernels.hpp | 18 +++++++++++- 2 files changed, 38 insertions(+), 8 deletions(-) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp index 9ccee0eabe0..a2ceae9d613 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp @@ -36,6 +36,8 @@ #include "constitutive/ConstitutivePassThru.hpp" +#include "constitutive/fluid/twophasefluid/TwoPhaseFluid.hpp" + #include #if defined( __INTEL_COMPILER ) @@ -48,6 +50,7 @@ namespace geos using namespace dataRepository; using namespace constitutive; using namespace fields::immiscibleMultiphaseFlow; +using namespace immiscibleMultiphaseKernels; real64 computeDensityL ( real64 P ) { return (1.0e-6 * (P * P)); @@ -204,15 +207,26 @@ void ImmiscibleMultiphaseFlow::initializePreSubGroups() } ); } + void ImmiscibleMultiphaseFlow::updateFluidModel( ObjectManagerBase & dataGroup ) const { GEOS_MARK_FUNCTION; - // arrayView1d< real64 const > const pres = dataGroup.getField< fields::flow::pressure >(); - // arrayView1d< real64 const > const temp = dataGroup.getField< fields::flow::temperature >(); - GEOS_UNUSED_VAR( dataGroup ); + arrayView1d< real64 const > const pres = dataGroup.getField< fields::flow::pressure >(); + + TwoPhaseFluid & fluid = getConstitutiveModel< TwoPhaseFluid >( dataGroup, dataGroup.getReference< string >( viewKeyStruct::fluidNamesString() ) ); + + constitutiveUpdatePassThru( fluid, [&] ( auto & castedFluid ) + { + using FluidType = TYPEOFREF( castedFluid ); + typename FluidType::KernelWrapper fluidWrapper = castedFluid.createKernelWrapper(); + + FluidUpdateKernel::launch< parallelDevicePolicy<> >( dataGroup.size(),fluidWrapper, pres ); + } ); } + + void ImmiscibleMultiphaseFlow::updateRelPermModel( ObjectManagerBase & dataGroup ) const { GEOS_MARK_FUNCTION; @@ -518,7 +532,6 @@ void ImmiscibleMultiphaseFlow::assembleSystem( real64 const GEOS_UNUSED_PARAM( t - void ImmiscibleMultiphaseFlow::assembleAccumulationTerm( DomainPartition & domain, DofManager const & dofManager, CRSMatrixView< real64, globalIndex const > const & localMatrix, @@ -537,9 +550,10 @@ void ImmiscibleMultiphaseFlow::assembleAccumulationTerm( DomainPartition & domai { string const dofKey = dofManager.getKey( viewKeyStruct::elemDofFieldString() ); string const & solidName = subRegion.getReference< string >( viewKeyStruct::solidNamesString() ); + string const & fluidName = subRegion.getReference< string >( viewKeyStruct::fluidNamesString() ); // The line below needs to be used once we have a fluid model - // MultiFluidBase const & fluid = getConstitutiveModel< MultiFluidBase >( subRegion, fluidName ); + TwoPhaseFluid const & fluid = getConstitutiveModel< TwoPhaseFluid >( subRegion, fluidName ); CoupledSolidBase const & solid = getConstitutiveModel< CoupledSolidBase >( subRegion, solidName ); arrayView1d< real64 const > const pres = subRegion.getField< fields::flow::pressure >(); @@ -552,8 +566,8 @@ void ImmiscibleMultiphaseFlow::assembleAccumulationTerm( DomainPartition & domai arrayView2d< real64 const > const dPoro_dPres = solid.getDporosity_dPressure(); arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFrac= subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); // The two lines below need to be used once we have a fluid model - //arrayView3d< real64 const, immiscibleFlow::USD_PHASE > m_phaseDens = fluid.phaseDensity(); - //arrayView4d< real64 const, immiscibleFlow::USD_PHASE_DS > m_dPhaseDens = fluid.dPhaseDensity(); + arrayView3d< real64 const, multifluid::USD_PHASE > m_phaseDens = fluid.phaseDensity(); + arrayView4d< real64 const, multifluid::USD_PHASE_DC > m_dPhaseDens = fluid.dPhaseDensity(); arrayView2d< real64 const, immiscibleFlow::USD_PHASE > phaseDens = subRegion.getField< fields::immiscibleMultiphaseFlow::phaseDensity>(); arrayView2d< real64 const, immiscibleFlow::USD_PHASE > dPhaseDens = subRegion.getField< fields::immiscibleMultiphaseFlow::dPhaseDensity>(); arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const PhaseMass_n = subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseMass_n >(); diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseKernels.hpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseKernels.hpp index 63e562674cb..2d2090bd77e 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseKernels.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseKernels.hpp @@ -874,7 +874,23 @@ class PhaseMobilityKernelFactory }; - +struct FluidUpdateKernel +{ + template< typename POLICY, typename FLUID_WRAPPER > + static void + launch( localIndex const size, + FLUID_WRAPPER const & fluidWrapper, + arrayView1d< real64 const > const & pres ) + { + forAll< POLICY >( size, [=] GEOS_HOST_DEVICE ( localIndex const k ) + { + for( localIndex q = 0; q < fluidWrapper.numGauss(); ++q ) + { + fluidWrapper.update( k, q, pres[k] ); + } + } ); + } +}; } // namesace immiscible multiphasekernels From 02287f74c7f361c1a197509ea6efcc56ced6041e Mon Sep 17 00:00:00 2001 From: Randolph Settgast Date: Tue, 17 Sep 2024 15:48:25 -0700 Subject: [PATCH 026/102] changes from commit that was removed --- host-configs/Stanford/ubuntu22.cmake | 44 +++++++++++++++++++ .../immiscible_2phaseFlow_1d.xml | 7 +++ 2 files changed, 51 insertions(+) create mode 100644 host-configs/Stanford/ubuntu22.cmake diff --git a/host-configs/Stanford/ubuntu22.cmake b/host-configs/Stanford/ubuntu22.cmake new file mode 100644 index 00000000000..39bca094e3e --- /dev/null +++ b/host-configs/Stanford/ubuntu22.cmake @@ -0,0 +1,44 @@ +# file: your-platform.cmake + +# detect host and name the configuration file +site_name(HOST_NAME) +set(CONFIG_NAME "ubuntu22" CACHE PATH "") +message("CONFIG_NAME = ${CONFIG_NAME}") + +# set paths to C, C++, and Fortran compilers. Note that while GEOS does not contain any Fortran code, +# some of the third-party libraries do contain Fortran code. Thus a Fortran compiler must be specified. +set(CMAKE_C_COMPILER "/usr/bin/gcc" CACHE PATH "") +set(CMAKE_CXX_COMPILER "/usr/bin/g++" CACHE PATH "") +set(CMAKE_Fortran_COMPILER "/usr/bin/gfortran" CACHE PATH "") +set(ENABLE_FORTRAN OFF CACHE BOOL "" FORCE) + +# enable MPI and set paths to compilers and executable. +# Note that the MPI compilers are wrappers around standard serial compilers. +# Therefore, the MPI compilers must wrap the appropriate serial compilers specified +# in CMAKE_C_COMPILER, CMAKE_CXX_COMPILER, and CMAKE_Fortran_COMPILER. +set(ENABLE_MPI ON CACHE BOOL "") +set(MPI_C_COMPILER "/usr/bin/mpicc" CACHE PATH "") +set(MPI_CXX_COMPILER "/usr/bin/mpicxx" CACHE PATH "") +set(MPI_Fortran_COMPILER "/usr/bin/mpifort" CACHE PATH "") +set(MPIEXEC "/usr/bin/mpirun" CACHE PATH "") + +# define the path to blas and lapack +#set( BLAS_LIBRARIES /home/rpiazza/lib/lapack-3.11.0-linux-x86_64/libblas.so CACHE PATH "" FORCE ) +#set( LAPACK_LIBRARIES /home/rpiazza/lib/lapack-3.11.0-linux-x86_64/liblapack.so CACHE PATH "" FORCE ) + +# disable CUDA and OpenMP +set(ENABLE_CUDA OFF CACHE BOOL "" FORCE) +set(ENABLE_OPENMP OFF CACHE BOOL "" FORCE) + +# enable PVTPackage +set(ENABLE_PVTPackage ON CACHE BOOL "" FORCE) + +# enable tests +set(ENABLE_GTEST_DEATH_TESTS ON CACHE BOOL "" FORCE ) + +# define the path to your compiled installation directory +set(GEOS_TPL_DIR "/home/rpiazza/two-phase/thirdPartyLibs/install-ubuntu22-debug" CACHE PATH "") +#set(GEOSX_TPL_DIR "${GEOSX_TPL_DIR}" CACHE PATH "" FORCE) +# let GEOS define some third party libraries information for you +#include(${CMAKE_CURRENT_LIST_DIR}/tpls.cmake) +include(${CMAKE_CURRENT_LIST_DIR}/../tpls.cmake) diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscible_2phaseFlow_1d.xml b/inputFiles/immiscibleMultiphaseFlow/immiscible_2phaseFlow_1d.xml index ecbf73253af..35fec304eda 100644 --- a/inputFiles/immiscibleMultiphaseFlow/immiscible_2phaseFlow_1d.xml +++ b/inputFiles/immiscibleMultiphaseFlow/immiscible_2phaseFlow_1d.xml @@ -84,6 +84,13 @@ compressibility="5e-10" viscosibility="0.0"/> + + Date: Wed, 18 Sep 2024 19:24:50 -0500 Subject: [PATCH 027/102] Fixed fluid initialization in flow solver, updated xml input file. --- .../immiscible_2phaseFlow_1d.xml | 34 +++++++++++-- .../fluidFlow/ImmiscibleMultiphaseFlow.cpp | 24 ++++++--- .../fluidFlow/ImmiscibleMultiphaseKernels.hpp | 50 ++++++++++--------- 3 files changed, 75 insertions(+), 33 deletions(-) diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscible_2phaseFlow_1d.xml b/inputFiles/immiscibleMultiphaseFlow/immiscible_2phaseFlow_1d.xml index 35fec304eda..d7f3553331c 100644 --- a/inputFiles/immiscibleMultiphaseFlow/immiscible_2phaseFlow_1d.xml +++ b/inputFiles/immiscibleMultiphaseFlow/immiscible_2phaseFlow_1d.xml @@ -72,11 +72,39 @@ + materialList="{ fluid, rock, relperm }"/> + + + + + + + + + + - + + - + scale="3e6"/> + + + + diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp index 9a71df6e7dc..6d1ab967999 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp @@ -293,16 +293,51 @@ void ImmiscibleMultiphaseFlow::updateCapPressureModel( ObjectManagerBase & dataG } } + void ImmiscibleMultiphaseFlow::updateFluidState( ElementSubRegionBase & subRegion ) const { GEOS_MARK_FUNCTION; updateFluidModel( subRegion ); + updatePhaseMass( subRegion ); updateRelPermModel( subRegion ); updatePhaseMobility( subRegion ); updateCapPressureModel( subRegion ); } + +void ImmiscibleMultiphaseFlow::updatePhaseMass( ElementSubRegionBase & subRegion ) const +{ + GEOS_MARK_FUNCTION; + + string const & solidName = subRegion.getReference< string >( viewKeyStruct::solidNamesString() ); + string const & fluidName = subRegion.getReference< string >( viewKeyStruct::fluidNamesString() ); + + TwoPhaseFluid const & fluid = getConstitutiveModel< TwoPhaseFluid >( subRegion, fluidName ); + CoupledSolidBase const & solid = getConstitutiveModel< CoupledSolidBase >( subRegion, solidName ); + + integer const numofPhases = 2; + arrayView1d< real64 const > const volume = subRegion.getElementVolume(); + arrayView2d< real64 const > const porosity = solid.getPorosity(); + + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFrac= subRegion.getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); + arrayView3d< real64 const, multifluid::USD_PHASE > phaseDens = fluid.phaseDensity(); + arrayView2d< real64, immiscibleFlow::USD_PHASE > const phaseMass = subRegion.getField< fields::immiscibleMultiphaseFlow::phaseMass >(); + + // Might be needed for geomechanics????? if so, need to change the accumulation as well? + //arrayView1d< real64 > const deltaVolume = subRegion.getField< fields::flow::deltaVolume >(); + + forAll< parallelDevicePolicy<> >( subRegion.size(), [=] GEOS_HOST_DEVICE ( localIndex const ei ) + { + real64 const poreVolume = volume[ei] * porosity[ei][0]; + for( integer ip = 0; ip < 2; ++ip ) + { + phaseMass[ei][ip] = poreVolume * phaseVolFrac[ei][ip] * phaseDens[ei][0][ip]; + } + }); +} + + void ImmiscibleMultiphaseFlow::updatePhaseMobility( ObjectManagerBase & dataGroup ) const { GEOS_MARK_FUNCTION; @@ -431,6 +466,8 @@ void ImmiscibleMultiphaseFlow::initializeFluidState( MeshLevel & mesh, arrayView1d< real64 > const initTemp = subRegion.template getField< fields::flow::initialTemperature >(); initPres.setValues< parallelDevicePolicy<> >( pres ); initTemp.setValues< parallelDevicePolicy<> >( temp ); + + // TODO: Missing updatePhaseMass? } ); } @@ -620,19 +657,6 @@ void ImmiscibleMultiphaseFlow::assembleAccumulationTerm( DomainPartition & domai for( integer ip = 0; ip < numofPhases; ++ip ) { - - // The few lines of code below are to be used if we want to use free functions for the phase density (to test the derivatives) - // real64 const pressure = pres[ei]; - - // real64 phaseDens = computeDensityV ( pressure ); - // real64 dPhaseDens = computedDensitydPV ( pressure ); - - // if( ip == 1) - // { - // phaseDens = computeDensityL ( pressure ); - // dPhaseDens = computedDensitydPL ( pressure ); - //} - real64 const phaseMass = poreVolume * phaseVolFrac[ei][ip] * phaseDens[ei][0][ip]; real64 const phaseMass_n = PhaseMass_n[ei][ip]; @@ -1052,7 +1076,11 @@ void ImmiscibleMultiphaseFlow::saveConvergedState( ElementSubRegionBase & subReg subRegion.getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction_n >(); phaseVolFrac_n.setValues< parallelDevicePolicy<> >( phaseVolFrac ); - + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseMass = + subRegion.getField< fields::immiscibleMultiphaseFlow::phaseMass >(); + arrayView2d< real64, immiscibleFlow::USD_PHASE > const phaseMass_n = + subRegion.getField< fields::immiscibleMultiphaseFlow::phaseMass_n >(); + phaseMass_n.setValues< parallelDevicePolicy<> >( phaseMass ); } diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp index 83e0e0739c9..ce5164eb16b 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp @@ -206,6 +206,12 @@ class ImmiscibleMultiphaseFlow : public FlowSolverBase */ void updateFluidModel( ObjectManagerBase & dataGroup ) const; + /** + * @brief Function to update fluid mass + * @param subRegion subregion that contains the fields + */ + void updatePhaseMass( ElementSubRegionBase & subRegion ) const; + /** * @brief Update all relevant relperm models using current values of phase volume fraction * @param dataGroup the group storing the required fields From 98e2c14641938c9a265d2053d2a0756a92f75ffa Mon Sep 17 00:00:00 2001 From: DENEL Bertrand Date: Thu, 3 Oct 2024 18:54:29 -0500 Subject: [PATCH 038/102] Applied uncrustify formatting. --- .../fluidFlow/ImmiscibleMultiphaseFlow.cpp | 292 +++++++++--------- .../fluidFlow/ImmiscibleMultiphaseFlow.hpp | 4 +- .../ImmiscibleMultiphaseFlowFields.hpp | 2 +- .../fluidFlow/ImmiscibleMultiphaseKernels.hpp | 174 ++++++----- 4 files changed, 238 insertions(+), 234 deletions(-) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp index 6d1ab967999..a0f0be788a2 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp @@ -53,23 +53,6 @@ using namespace constitutive; using namespace fields::immiscibleMultiphaseFlow; using namespace immiscibleMultiphaseKernels; -real64 computeDensityL ( real64 P ) { - return (1.0e-6 * (P * P)); -} - -real64 computedDensitydPL ( real64 P ) { - return (1.0e-6 * 2.0 * (P)); -} - -real64 computeDensityV ( real64 P ) { - return (1.0e-8 * (P * P)); -} - -real64 computedDensitydPV ( real64 P ) { - return (1.0e-8 * 2.0 * (P)); -} - - ImmiscibleMultiphaseFlow::ImmiscibleMultiphaseFlow( const string & name, Group * const parent ) @@ -181,7 +164,6 @@ void ImmiscibleMultiphaseFlow::setConstitutiveNames( ElementSubRegionBase & subR - string & relPermName = subRegion.registerWrapper< string >( viewKeyStruct::relPermNamesString() ). setPlotLevel( PlotLevel::NOPLOT ). setRestartFlags( RestartFlags::NO_WRITE ). @@ -236,8 +218,8 @@ void ImmiscibleMultiphaseFlow::updateFluidModel( ObjectManagerBase & dataGroup ) { using FluidType = TYPEOFREF( castedFluid ); typename FluidType::KernelWrapper fluidWrapper = castedFluid.createKernelWrapper(); - - FluidUpdateKernel::launch< parallelDevicePolicy<> >( dataGroup.size(),fluidWrapper, pres ); + + FluidUpdateKernel::launch< parallelDevicePolicy<> >( dataGroup.size(), fluidWrapper, pres ); } ); } @@ -323,18 +305,18 @@ void ImmiscibleMultiphaseFlow::updatePhaseMass( ElementSubRegionBase & subRegion arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFrac= subRegion.getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); arrayView3d< real64 const, multifluid::USD_PHASE > phaseDens = fluid.phaseDensity(); arrayView2d< real64, immiscibleFlow::USD_PHASE > const phaseMass = subRegion.getField< fields::immiscibleMultiphaseFlow::phaseMass >(); - + // Might be needed for geomechanics????? if so, need to change the accumulation as well? //arrayView1d< real64 > const deltaVolume = subRegion.getField< fields::flow::deltaVolume >(); - + forAll< parallelDevicePolicy<> >( subRegion.size(), [=] GEOS_HOST_DEVICE ( localIndex const ei ) { - real64 const poreVolume = volume[ei] * porosity[ei][0]; - for( integer ip = 0; ip < 2; ++ip ) - { - phaseMass[ei][ip] = poreVolume * phaseVolFrac[ei][ip] * phaseDens[ei][0][ip]; - } - }); + real64 const poreVolume = volume[ei] * porosity[ei][0]; + for( integer ip = 0; ip < 2; ++ip ) + { + phaseMass[ei][ip] = poreVolume * phaseVolFrac[ei][ip] * phaseDens[ei][0][ip]; + } + } ); } @@ -344,17 +326,18 @@ void ImmiscibleMultiphaseFlow::updatePhaseMobility( ObjectManagerBase & dataGrou // note that the phase mobility computed here also includes phase density string const & fluidName = dataGroup.getReference< string >( viewKeyStruct::fluidNamesString() ); - TwoPhaseFluid const & fluid = getConstitutiveModel< TwoPhaseFluid >( dataGroup, fluidName ); + TwoPhaseFluid const & fluid = getConstitutiveModel< TwoPhaseFluid >( dataGroup, fluidName ); string const & relpermName = dataGroup.getReference< string >( viewKeyStruct::relPermNamesString() ); RelativePermeabilityBase const & relperm = getConstitutiveModel< RelativePermeabilityBase >( dataGroup, relpermName ); immiscibleMultiphaseKernels:: - PhaseMobilityKernelFactory:: - createAndLaunch< parallelDevicePolicy<> >( m_numPhases, - dataGroup, - fluid, - relperm ); } + PhaseMobilityKernelFactory:: + createAndLaunch< parallelDevicePolicy<> >( m_numPhases, + dataGroup, + fluid, + relperm ); +} void ImmiscibleMultiphaseFlow::initializeFluidState( MeshLevel & mesh, DomainPartition & GEOS_UNUSED_PARAM( domain ), @@ -371,7 +354,7 @@ void ImmiscibleMultiphaseFlow::initializeFluidState( MeshLevel & mesh, updateFluidModel( subRegion ); } ); - + // for some reason CUDA does not want the host_device lambda to be defined inside the generic lambda // I need the exact type of the subRegion for updateSolidflowProperties to work well. mesh.getElemManager().forElementSubRegions< CellElementSubRegion, @@ -571,7 +554,7 @@ void ImmiscibleMultiphaseFlow::assembleSystem( real64 const GEOS_UNUSED_PARAM( t CRSMatrixView< real64, globalIndex const > const & localMatrix, arrayView1d< real64 > const & localRhs ) { - GEOS_MARK_FUNCTION; + GEOS_MARK_FUNCTION; assembleAccumulationTerm( domain, dofManager, @@ -611,80 +594,80 @@ void ImmiscibleMultiphaseFlow::assembleAccumulationTerm( DomainPartition & domai TwoPhaseFluid const & fluid = getConstitutiveModel< TwoPhaseFluid >( subRegion, fluidName ); CoupledSolidBase const & solid = getConstitutiveModel< CoupledSolidBase >( subRegion, solidName ); - //arrayView1d< real64 const > const pres = subRegion.getField< fields::flow::pressure >(); - integer const numofPhases = 2; - globalIndex const rankOffset = dofManager.rankOffset(); - arrayView1d< globalIndex const > const dofNumber = subRegion.getReference< array1d< globalIndex > >( dofKey ); - arrayView1d< integer const > const elemGhostRank= subRegion.ghostRank(); - arrayView1d< real64 const > const volume = subRegion.getElementVolume(); - arrayView2d< real64 const > const porosity = solid.getPorosity(); - arrayView2d< real64 const > const dPoro_dPres = solid.getDporosity_dPressure(); - arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFrac= subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); - arrayView3d< real64 const, multifluid::USD_PHASE > phaseDens = fluid.phaseDensity(); - arrayView4d< real64 const, multifluid::USD_PHASE_DC > dPhaseDens = fluid.dPhaseDensity(); - arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const PhaseMass_n = subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseMass_n >(); - - // The line below is to be used if we want to use the total mass flux formulation - //BitFlags< ElementBasedAssemblyKernelFlags > m_kernelFlags = kernelFlags; - - - integer const numElems = subRegion.size(); - forAll< parallelDevicePolicy<> >( - numElems, [=] GEOS_HOST_DEVICE ( localIndex const ei ) - { - if( elemGhostRank( ei ) >= 0 ) + //arrayView1d< real64 const > const pres = subRegion.getField< fields::flow::pressure >(); + integer const numofPhases = 2; + globalIndex const rankOffset = dofManager.rankOffset(); + arrayView1d< globalIndex const > const dofNumber = subRegion.getReference< array1d< globalIndex > >( dofKey ); + arrayView1d< integer const > const elemGhostRank= subRegion.ghostRank(); + arrayView1d< real64 const > const volume = subRegion.getElementVolume(); + arrayView2d< real64 const > const porosity = solid.getPorosity(); + arrayView2d< real64 const > const dPoro_dPres = solid.getDporosity_dPressure(); + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFrac= subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); + arrayView3d< real64 const, multifluid::USD_PHASE > phaseDens = fluid.phaseDensity(); + arrayView4d< real64 const, multifluid::USD_PHASE_DC > dPhaseDens = fluid.dPhaseDensity(); + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const PhaseMass_n = subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseMass_n >(); + + // The line below is to be used if we want to use the total mass flux formulation + //BitFlags< ElementBasedAssemblyKernelFlags > m_kernelFlags = kernelFlags; + + + integer const numElems = subRegion.size(); + forAll< parallelDevicePolicy<> >( + numElems, [=] GEOS_HOST_DEVICE ( localIndex const ei ) { - return; - } + if( elemGhostRank( ei ) >= 0 ) + { + return; + } - // setup - globalIndex dofIndices[2]{}; - real64 localResidual[2]{}; - real64 localJacobian[2][2]{}; + // setup + globalIndex dofIndices[2]{}; + real64 localResidual[2]{}; + real64 localJacobian[2][2]{}; - real64 const poreVolume = volume[ei] * porosity[ei][0]; - real64 const dPoreVolume_dPres = volume[ei] * dPoro_dPres[ei][0]; + real64 const poreVolume = volume[ei] * porosity[ei][0]; + real64 const dPoreVolume_dPres = volume[ei] * dPoro_dPres[ei][0]; - localIndex localRow = dofNumber[ei] - rankOffset; - - for( integer idof = 0; idof < 2; ++idof ) - { - dofIndices[idof] = dofNumber[ei] + idof; - } + localIndex localRow = dofNumber[ei] - rankOffset; - // compute accumulation + for( integer idof = 0; idof < 2; ++idof ) + { + dofIndices[idof] = dofNumber[ei] + idof; + } + // compute accumulation - for( integer ip = 0; ip < numofPhases; ++ip ) - { - real64 const phaseMass = poreVolume * phaseVolFrac[ei][ip] * phaseDens[ei][0][ip]; - real64 const phaseMass_n = PhaseMass_n[ei][ip]; - localResidual[ip] += phaseMass - phaseMass_n; + for( integer ip = 0; ip < numofPhases; ++ip ) + { + real64 const phaseMass = poreVolume * phaseVolFrac[ei][ip] * phaseDens[ei][0][ip]; + real64 const phaseMass_n = PhaseMass_n[ei][ip]; + + localResidual[ip] += phaseMass - phaseMass_n; - real64 const dPhaseMass_dP = dPoreVolume_dPres * phaseVolFrac[ei][ip] * phaseDens[ei][0][ip] + real64 const dPhaseMass_dP = dPoreVolume_dPres * phaseVolFrac[ei][ip] * phaseDens[ei][0][ip] + poreVolume * phaseVolFrac[ei][ip] * dPhaseDens[ei][0][ip][0]; - localJacobian[ip][0] += dPhaseMass_dP; + localJacobian[ip][0] += dPhaseMass_dP; - real64 const dPhaseMass_dS = poreVolume * phaseDens[ei][0][ip]; - - localJacobian[ip][1] += dPhaseMass_dS; - } + real64 const dPhaseMass_dS = poreVolume * phaseDens[ei][0][ip]; - // complete - - integer const numRows = numofPhases; + localJacobian[ip][1] += dPhaseMass_dS; + } - for( integer i = 0; i < numRows; ++i ) - { - localRhs[localRow + i] += localResidual[i]; - localMatrix.addToRow< serialAtomic >( localRow + i, - dofIndices, - localJacobian[i], - 2); - } + // complete - } ); + integer const numRows = numofPhases; + + for( integer i = 0; i < numRows; ++i ) + { + localRhs[localRow + i] += localResidual[i]; + localMatrix.addToRow< serialAtomic >( localRow + i, + dofIndices, + localJacobian[i], + 2 ); + } + + } ); } ); } ); @@ -697,7 +680,7 @@ void ImmiscibleMultiphaseFlow::assembleFluxTerms( real64 const dt, DofManager const & dofManager, CRSMatrixView< real64, globalIndex const > const & localMatrix, arrayView1d< real64 > const & localRhs ) const -{ +{ GEOS_MARK_FUNCTION; NumericalMethodsManager const & numericalMethodManager = domain.getNumericalMethodManager(); @@ -714,32 +697,32 @@ void ImmiscibleMultiphaseFlow::assembleFluxTerms( real64 const dt, { typename TYPEOFREF( stencil ) ::KernelWrapper stencilWrapper = stencil.createKernelWrapper(); immiscibleMultiphaseKernels:: - FaceBasedAssemblyKernelFactory::createAndLaunch< parallelDevicePolicy<> >( m_numPhases, - dofManager.rankOffset(), - dofKey, - m_hasCapPressure, - m_useTotalMassEquation, - getName(), - mesh.getElemManager(), - stencilWrapper, - dt, - localMatrix.toViewConstSizes(), - localRhs.toView() ); - } ); + FaceBasedAssemblyKernelFactory::createAndLaunch< parallelDevicePolicy<> >( m_numPhases, + dofManager.rankOffset(), + dofKey, + m_hasCapPressure, + m_useTotalMassEquation, + getName(), + mesh.getElemManager(), + stencilWrapper, + dt, + localMatrix.toViewConstSizes(), + localRhs.toView() ); + } ); } ); } // Ryan: Looks like this will need to be overwritten as well... // I have left the CompositionalMultiphaseFVM implementation for reference void ImmiscibleMultiphaseFlow::setupDofs( DomainPartition const & domain, - DofManager & dofManager ) const + DofManager & dofManager ) const { - GEOS_UNUSED_VAR(domain, dofManager); + GEOS_UNUSED_VAR( domain, dofManager ); // add a field for the cell-centered degrees of freedom dofManager.addField( viewKeyStruct::elemDofFieldString(), - FieldLocation::Elem, - m_numDofPerCell, - getMeshTargets() ); + FieldLocation::Elem, + m_numDofPerCell, + getMeshTargets() ); //// this call with instruct GEOS to reorder the dof numbers //dofManager.setLocalReorderingType( viewKeyStruct::elemDofFieldString(), @@ -802,8 +785,9 @@ void ImmiscibleMultiphaseFlow::applyDirichletBC( real64 const time_n, fields::flow::pressure::key(), fields::flow::bcPressure::key() ); // 2. Apply saturation BC (phase volume fraction) and store in a separate field //applyFieldValue< ElementSubRegionBase >( time_n, dt, mesh, bcLogMessage, - // fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key(), fields::immiscibleMultiphaseFlow::bcPhaseVolumeFraction::key() ); - + // fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key(), + // fields::immiscibleMultiphaseFlow::bcPhaseVolumeFraction::key() ); + globalIndex const rankOffset = dofManager.rankOffset(); string const dofKey = dofManager.getKey( viewKeyStruct::elemDofFieldString() ); @@ -816,13 +800,14 @@ void ImmiscibleMultiphaseFlow::applyDirichletBC( real64 const time_n, SortedArrayView< localIndex const > const & targetSet, ElementSubRegionBase & subRegion, string const & ) - { + { arrayView1d< real64 const > const bcPres = subRegion.getReference< array1d< real64 > >( fields::flow::bcPressure::key() ); //arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const bcPhaseVolFraction = - //subRegion.getReference< array2d< real64, immiscibleFlow::LAYOUT_PHASE > >( fields::immiscibleMultiphaseFlow::bcPhaseVolumeFraction::key() ); - + //subRegion.getReference< array2d< real64, immiscibleFlow::LAYOUT_PHASE > >( + // fields::immiscibleMultiphaseFlow::bcPhaseVolumeFraction::key() ); + arrayView1d< integer const > const ghostRank = subRegion.getReference< array1d< integer > >( ObjectManagerBase::viewKeyStruct::ghostRankString() ); arrayView1d< globalIndex const > const dofNumber = @@ -830,7 +815,8 @@ void ImmiscibleMultiphaseFlow::applyDirichletBC( real64 const time_n, arrayView1d< real64 const > const pres = subRegion.getReference< array1d< real64 > >( fields::flow::pressure::key() ); //arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFraction = - //subRegion.getReference< array2d< real64, immiscibleFlow::LAYOUT_PHASE > >( fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key() ); + //subRegion.getReference< array2d< real64, immiscibleFlow::LAYOUT_PHASE > >( + // fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key() ); integer const numPhase = m_numPhases; forAll< parallelDevicePolicy<> >( targetSet.size(), [=] GEOS_HOST_DEVICE ( localIndex const a ) @@ -866,15 +852,15 @@ void ImmiscibleMultiphaseFlow::applyDirichletBC( real64 const time_n, // localRhs[localRow + ip + 1] = rhsValue; // } } ); - } ); + } ); } ); } real64 ImmiscibleMultiphaseFlow::calculateResidualNorm( real64 const & GEOS_UNUSED_PARAM( time_n ), - real64 const & GEOS_UNUSED_PARAM( dt ), - DomainPartition const & domain, - DofManager const & dofManager, - arrayView1d< real64 const > const & localRhs ) + real64 const & GEOS_UNUSED_PARAM( dt ), + DomainPartition const & domain, + DofManager const & dofManager, + arrayView1d< real64 const > const & localRhs ) { GEOS_MARK_FUNCTION; integer constexpr numNorm = 1; // mass balance @@ -907,22 +893,22 @@ real64 ImmiscibleMultiphaseFlow::calculateResidualNorm( real64 const & GEOS_UNUS // step 1: compute the norm in the subRegion - real64 subRegionFlowResidualNorm[1]{}; - real64 subRegionFlowResidualNormalizer[1]{}; - + real64 subRegionFlowResidualNorm[1]{}; + real64 subRegionFlowResidualNormalizer[1]{}; + immiscibleMultiphaseKernels:: - ResidualNormKernelFactory::createAndLaunch< parallelDevicePolicy<> >( normType, - 2, - rankOffset, - dofKey, - localRhs, - subRegion, - solid, - m_nonlinearSolverParameters.m_minNormalizer, - subRegionFlowResidualNorm, - subRegionFlowResidualNormalizer ); - subRegionResidualNorm[0] = subRegionFlowResidualNorm[0]; - subRegionResidualNormalizer[0] = subRegionFlowResidualNormalizer[0]; + ResidualNormKernelFactory::createAndLaunch< parallelDevicePolicy<> >( normType, + 2, + rankOffset, + dofKey, + localRhs, + subRegion, + solid, + m_nonlinearSolverParameters.m_minNormalizer, + subRegionFlowResidualNorm, + subRegionFlowResidualNormalizer ); + subRegionResidualNorm[0] = subRegionFlowResidualNorm[0]; + subRegionResidualNormalizer[0] = subRegionFlowResidualNormalizer[0]; // step 2: first reduction across meshBodies/regions/subRegions if( normType == solverBaseKernels::NormType::Linf ) @@ -940,21 +926,21 @@ real64 ImmiscibleMultiphaseFlow::calculateResidualNorm( real64 const & GEOS_UNUS real64 residualNorm = 0.0; residualNorm = localResidualNorm[0]; -if( normType == solverBaseKernels::NormType::Linf ) - { - solverBaseKernels::LinfResidualNormHelper::computeGlobalNorm( localResidualNorm[0], residualNorm ); - } - else - { - solverBaseKernels::L2ResidualNormHelper::computeGlobalNorm( localResidualNorm[0], localResidualNormalizer[0], residualNorm ); - } + if( normType == solverBaseKernels::NormType::Linf ) + { + solverBaseKernels::LinfResidualNormHelper::computeGlobalNorm( localResidualNorm[0], residualNorm ); + } + else + { + solverBaseKernels::L2ResidualNormHelper::computeGlobalNorm( localResidualNorm[0], localResidualNormalizer[0], residualNorm ); + } + + if( getLogLevel() >= 1 && logger::internal::rank == 0 ) + { + std::cout << GEOS_FMT( " ( R{} ) = ( {:4.2e} )", coupledSolverAttributePrefix(), residualNorm ); + } - if( getLogLevel() >= 1 && logger::internal::rank == 0 ) - { - std::cout << GEOS_FMT( " ( R{} ) = ( {:4.2e} )", coupledSolverAttributePrefix(), residualNorm ); - } - return residualNorm; } diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp index ce5164eb16b..65961ec2df8 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp @@ -88,7 +88,7 @@ class ImmiscibleMultiphaseFlow : public FlowSolverBase DofManager const & dofManager, CRSMatrixView< real64, globalIndex const > const & localMatrix, arrayView1d< real64 > const & localRhs ) override; - + virtual real64 calculateResidualNorm( real64 const & time_n, real64 const & dt, @@ -106,7 +106,7 @@ class ImmiscibleMultiphaseFlow : public FlowSolverBase DomainPartition & domain, DofManager const & dofManager, CRSMatrixView< real64, globalIndex const > const & localMatrix, - arrayView1d< real64 > const & localRhs ) override; + arrayView1d< real64 > const & localRhs ) override; virtual void resetStateToBeginningOfStep( DomainPartition & domain ) override; diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlowFields.hpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlowFields.hpp index 64752b84ecb..48d560815d9 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlowFields.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlowFields.hpp @@ -59,7 +59,7 @@ DECLARE_FIELD( bcPhaseVolumeFraction, 0, LEVEL_0, WRITE_AND_READ, - "Boundary condition phase volume fraction" ); + "Boundary condition phase volume fraction" ); DECLARE_FIELD( phaseMass, "phaseMass", diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseKernels.hpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseKernels.hpp index 2eb245b5aae..97690653236 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseKernels.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseKernels.hpp @@ -44,7 +44,6 @@ #include "physicsSolvers/SolverBaseKernels.hpp" namespace geos - { namespace immiscibleMultiphaseKernels { @@ -75,26 +74,26 @@ class FaceBasedAssemblyKernelBase using ImmiscibleMultiphaseFlowAccessors = StencilAccessors< fields::ghostRank, fields::flow::pressure, - fields::flow::gravityCoefficient, + fields::flow::gravityCoefficient, fields::immiscibleMultiphaseFlow::phaseMobility, - fields::immiscibleMultiphaseFlow::dPhaseMobility >; + fields::immiscibleMultiphaseFlow::dPhaseMobility >; using MultiphaseFluidAccessors = StencilMaterialAccessors< constitutive::TwoPhaseFluid, fields::twophasefluid::phaseDensity, - fields::twophasefluid::dPhaseDensity >; + fields::twophasefluid::dPhaseDensity >; using CapPressureAccessors = StencilMaterialAccessors< CapillaryPressureBase, fields::cappres::phaseCapPressure, - fields::cappres::dPhaseCapPressure_dPhaseVolFraction >; + fields::cappres::dPhaseCapPressure_dPhaseVolFraction >; using PermeabilityAccessors = StencilMaterialAccessors< PermeabilityBase, fields::permeability::permeability, - fields::permeability::dPerm_dPressure >; + fields::permeability::dPerm_dPressure >; - using Deriv = immiscibleFlow::DerivativeOffset; + using Deriv = immiscibleFlow::DerivativeOffset; /** * @brief Constructor for the kernel interface @@ -111,8 +110,8 @@ class FaceBasedAssemblyKernelBase FaceBasedAssemblyKernelBase( integer const numPhases, globalIndex const rankOffset, DofNumberAccessor const & dofNumberAccessor, - ImmiscibleMultiphaseFlowAccessors const & multiPhaseFlowAccessors, - MultiphaseFluidAccessors const & fluidAccessors, + ImmiscibleMultiphaseFlowAccessors const & multiPhaseFlowAccessors, + MultiphaseFluidAccessors const & fluidAccessors, CapPressureAccessors const & capPressureAccessors, PermeabilityAccessors const & permeabilityAccessors, real64 const & dt, @@ -120,7 +119,7 @@ class FaceBasedAssemblyKernelBase arrayView1d< real64 > const & localRhs, integer const hasCapPressure, integer const useTotalMassEquation ) - : m_numPhases (numPhases), + : m_numPhases ( numPhases ), m_rankOffset( rankOffset ), m_dt( dt ), m_dofNumber( dofNumberAccessor.toNestedViewConst() ), @@ -130,7 +129,7 @@ class FaceBasedAssemblyKernelBase m_gravCoef( multiPhaseFlowAccessors.get( fields::flow::gravityCoefficient {} ) ), m_pres( multiPhaseFlowAccessors.get( fields::flow::pressure {} ) ), m_mob( multiPhaseFlowAccessors.get( fields::immiscibleMultiphaseFlow::phaseMobility {} ) ), - m_dMob( multiPhaseFlowAccessors.get( fields::immiscibleMultiphaseFlow::dPhaseMobility {} ) ), + m_dMob( multiPhaseFlowAccessors.get( fields::immiscibleMultiphaseFlow::dPhaseMobility {} ) ), m_dens( fluidAccessors.get( fields::twophasefluid::phaseDensity {} ) ), m_dDens_dPres( fluidAccessors.get( fields::twophasefluid::dPhaseDensity {} ) ), m_phaseCapPressure( capPressureAccessors.get( fields::cappres::phaseCapPressure {} ) ), @@ -139,7 +138,7 @@ class FaceBasedAssemblyKernelBase m_localRhs( localRhs ), m_hasCapPressure ( hasCapPressure ), m_useTotalMassEquation ( useTotalMassEquation ) - {GEOS_UNUSED_VAR(m_useTotalMassEquation);} + {GEOS_UNUSED_VAR( m_useTotalMassEquation );} protected: @@ -250,8 +249,8 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase : FaceBasedAssemblyKernelBase( numPhases, rankOffset, dofNumberAccessor, - multiPhaseFlowAccessors, - fluidAccessors, + multiPhaseFlowAccessors, + fluidAccessors, capPressureAccessors, permeabilityAccessors, dt, @@ -271,7 +270,7 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase */ struct StackVariables { - public: +public: /** * @brief Constructor for the stack variables @@ -336,7 +335,7 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase * @param[in] iconn the connection index * @param[in] stack the stack variables */ - + GEOS_HOST_DEVICE void setup( localIndex const iconn, StackVariables & stack ) const @@ -366,7 +365,8 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase StackVariables & stack, FUNC && kernelOp = NoOpFunc{} ) const { - // first, compute the transmissibilities at this face // get k and dk/dP from global arrays and place in stack + // first, compute the transmissibilities at this face // get k and dk/dP from global arrays + // and place in stack m_stencilWrapper.computeWeights( iconn, m_permeability, m_dPerm_dPres, @@ -384,7 +384,7 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase real64 densMean[numEqn]{}; real64 dDensMean_dP[numEqn][2]{}; - real64 presGrad[numEqn]{}; + real64 presGrad[numEqn]{}; real64 dPresGrad_dP[numEqn][2]{}; real64 gravHead[numEqn]{}; @@ -393,7 +393,7 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase real64 capGrad[numEqn]{}; real64 dCapGrad_dP[numEqn][2]{}; real64 dCapGrad_dS[numEqn][2]{}; - + real64 fluxVal[numEqn]{}; real64 dFlux_dP[numEqn][2]{}; real64 dFlux_dS[numEqn][2]{}; @@ -403,7 +403,7 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase real64 dMob_dS[numEqn][2]{}; real64 const trans[2] = { stack.transmissibility[connectionIndex][0], stack.transmissibility[connectionIndex][1] }; - real64 const dTrans_dP[2] = { stack.dTrans_dPres[connectionIndex][0], stack.dTrans_dPres[connectionIndex][1] }; + real64 const dTrans_dP[2] = { stack.dTrans_dPres[connectionIndex][0], stack.dTrans_dPres[connectionIndex][1] }; // cell indices localIndex const seri[2] = {m_seri( iconn, k[0] ), m_seri( iconn, k[1] )}; @@ -413,7 +413,7 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase // loop over phases for( integer ip = 0; ip < m_numPhases; ++ip ) { - // calculate quantities on primary connected cells + // calculate quantities on primary connected cells for( integer ke = 0; ke < 2; ++ke ) { // density @@ -456,12 +456,13 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase dGravHead_dP[ip][i] += dDensMean_dP[ip][i] * gravD; // dDPg/dP = {drho/dP1 * T g (z1 - z2) , drho/dP2 * T g (z1 - z2)} } - if ( m_hasCapPressure ) // check sign convention + if( m_hasCapPressure ) // check sign convention { real64 const capPres = m_phaseCapPressure[er][esr][ei][0][ip]; // Pc = Pc1 || Pc2 dCapGrad_dTrans -= signPotDiff[ke] * capPres; // dDPc/dT = (-Pc1 + Pc2) - pot -= trans[ke] * capPres; // Phi = T P1 - rho T g z1 - T Pc1 || -T P2 + rho T g z2 + T Pc2 - capGrad[ip] -= trans[ke] * capPres; // DPc = T (-Pc1 + Pc2) + pot -= trans[ke] * capPres; // Phi = T P1 - rho T g z1 - T Pc1 || -T P2 + rho T g z2 + T + // Pc2 + capGrad[ip] -= trans[ke] * capPres; // DPc = T (-Pc1 + Pc2) } potScale = fmax( potScale, fabs( pot ) ); // maxPhi = Phi1 > Phi2 ? Phi1 : Phi2 @@ -470,29 +471,35 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase for( integer ke = 0; ke < 2; ++ke ) { dPresGrad_dP[ip][ke] += dTrans_dP[ke] * dPresGrad_dTrans; // dDPv/dP = { T + dT/dP1 * (P1 - P2) , -T + dT/dP2 * (P1 - P2)} - dGravHead_dP[ip][ke] += dTrans_dP[ke] * dGravHead_dTrans; // dDPg/dP = { drho/dP1 * T g (z1 - z2) + dT/dP1 * rho g (z1 - z2) , + dGravHead_dP[ip][ke] += dTrans_dP[ke] * dGravHead_dTrans; // dDPg/dP = { drho/dP1 * T g (z1 - z2) + dT/dP1 * rho g (z1 - z2) , // drho/dP2 * T g (z1 - z2) + dT/dP2 * rho g (z1 - z2) } - if ( m_hasCapPressure ) + if( m_hasCapPressure ) { - real64 const dCapPres_dS = m_dPhaseCapPressure_dPhaseVolFrac[seri[ke]][sesri[ke]][sei[ke]][0][ip][ip]; // dPc/dS = dPc1/dS1 || dPc2/dS2 - dCapGrad_dP[ip][ke] += dTrans_dP[ke] * dCapGrad_dTrans; // dDPc/dP = { dT/dP1 * (-Pc1 + Pc2) , - // dT/dP2 * (-Pc1 + Pc2) } - dCapGrad_dS[ip][ke] -= trans[ke] * dCapPres_dS; // dDPc/dS = { -T * dPc1/dS1 , T * dPc2/dS2 } - } + real64 const dCapPres_dS = m_dPhaseCapPressure_dPhaseVolFrac[seri[ke]][sesri[ke]][sei[ke]][0][ip][ip]; // dPc/dS = dPc1/dS1 || + // dPc2/dS2 + dCapGrad_dP[ip][ke] += dTrans_dP[ke] * dCapGrad_dTrans; // dDPc/dP = { dT/dP1 * + // (-Pc1 + Pc2) , + // dT/dP2 * + // (-Pc1 + Pc2) } + dCapGrad_dS[ip][ke] -= trans[ke] * dCapPres_dS; // dDPc/dS = { -T * + // dPc1/dS1 , T * + // dPc2/dS2 } + } } // *** upwinding *** // compute potential gradient real64 potGrad = presGrad[ip] - gravHead[ip]; // DPhi = T (P1 - P2) - T rho g (z1 - z2) - if ( m_hasCapPressure ) + if( m_hasCapPressure ) { potGrad += capGrad[ip]; // DPhi = T (P1 - P2) - T rho g (z1 - z2) + T (-Pc1 + Pc2) } // compute upwinding tolerance real64 constexpr upwRelTol = 1e-8; - real64 const upwAbsTol = fmax( potScale * upwRelTol, LvArray::NumericLimits< real64 >::epsilon ); // abstol = maxPhi * tol > eps ? maxPhi * tol : eps + real64 const upwAbsTol = fmax( potScale * upwRelTol, LvArray::NumericLimits< real64 >::epsilon ); // abstol = maxPhi * tol > eps ? + // maxPhi * tol : eps // decide mobility coefficients - smooth variation in [-upwAbsTol; upwAbsTol] real64 const alpha = ( potGrad + upwAbsTol ) / ( 2 * upwAbsTol ); // alpha = (DPhi + abstol) / abstol / 2 @@ -502,7 +509,7 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase { localIndex const k_up = 1 - localIndex( fmax( fmin( alpha, 1.0 ), 0.0 ) ); // 1 upwind -> k_up = 0 || 2 upwind -> k_up = 1 - mobility[ip] = m_mob[seri[k_up]][sesri[k_up]][sei[k_up]][ip]; // M = Mupstream + mobility[ip] = m_mob[seri[k_up]][sesri[k_up]][sei[k_up]][ip]; // M = Mupstream dMob_dP[ip][k_up] = m_dMob[seri[k_up]][sesri[k_up]][sei[k_up]][ip][Deriv::dP]; // dM/dP = {dM/dP1 , 0} OR {0 , dM/dP2} dMob_dS[ip][k_up] = m_dMob[seri[k_up]][sesri[k_up]][sei[k_up]][ip][Deriv::dS]; // dM/dS = {dM/dS1 , 0} OR {0 , dM/dS2} } @@ -512,34 +519,40 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase for( integer ke = 0; ke < 2; ++ke ) { mobility[ip] += mobWeights[ke] * m_mob[seri[ke]][sesri[ke]][sei[ke]][ip]; // M = alpha * M1 + (1 - alpha) * M2 - dMob_dP[ip][ke] = mobWeights[ke] * m_dMob[seri[ke]][sesri[ke]][sei[ke]][ip][Deriv::dP]; // dM/dP = {alpha * dM1/dP1 , (1 - alpha) * dM2/dP2} - dMob_dS[ip][ke] = mobWeights[ke] * m_dMob[seri[ke]][sesri[ke]][sei[ke]][ip][Deriv::dS]; // dM/dP = {alpha * dM1/dS1 , (1 - alpha) * dM2/dS2} + dMob_dP[ip][ke] = mobWeights[ke] * m_dMob[seri[ke]][sesri[ke]][sei[ke]][ip][Deriv::dP]; // dM/dP = {alpha * dM1/dP1 , (1 - + // alpha) * dM2/dP2} + dMob_dS[ip][ke] = mobWeights[ke] * m_dMob[seri[ke]][sesri[ke]][sei[ke]][ip][Deriv::dS]; // dM/dP = {alpha * dM1/dS1 , (1 - + // alpha) * dM2/dS2} } } // pressure gradient depends on all points in the stencil for( integer ke = 0; ke < 2; ++ke ) { - dFlux_dP[ip][ke] += dPresGrad_dP[ip][ke]; // dF/dP = { T + dT/dP1 * (P1 - P2) , + dFlux_dP[ip][ke] += dPresGrad_dP[ip][ke]; // dF/dP = { T + dT/dP1 * (P1 - P2) , // -T + dT/dP2 * (P1 - P2) } } // gravitational head depends only on the two cells connected (same as mean density) - for( integer ke = 0; ke < 2; ++ke ) + for( integer ke = 0; ke < 2; ++ke ) { - dFlux_dP[ip][ke] -= dGravHead_dP[ip][ke]; // dF/dP = { T + dT/dP1 * (P1 - P2) - drho/dP1 * T g (z1 - z2) - dT/dP1 * rho g (z1 - z2) , - // -T + dT/dP2 * (P1 - P2) - drho/dP2 * T g (z1 - z2) - dT/dP2 * rho g (z1 - z2) } + dFlux_dP[ip][ke] -= dGravHead_dP[ip][ke]; // dF/dP = { T + dT/dP1 * (P1 - P2) - drho/dP1 * T g (z1 - z2) - dT/dP1 * rho g (z1 - + // z2) , + // -T + dT/dP2 * (P1 - P2) - drho/dP2 * T g (z1 - z2) - dT/dP2 * rho g (z1 - + // z2) } } // capillary pressure contribution - if ( m_hasCapPressure ) + if( m_hasCapPressure ) { for( integer ke = 0; ke < 2; ++ke ) - { - dFlux_dP[ip][ke] += dCapGrad_dP[ip][ke]; // dF/dP = { T + dT/dP1 * (P1 - P2) - drho/dP1 * T g (z1 - z2) - dT/dP1 * rho g (z1 - z2) + dT/dP1 * (-Pc1 + Pc2) , - // -T + dT/dP2 * (P1 - P2) - drho/dP2 * T g (z1 - z2) - dT/dP2 * rho g (z1 - z2) + dT/dP2 * (-Pc1 + Pc2) } + { + dFlux_dP[ip][ke] += dCapGrad_dP[ip][ke]; // dF/dP = { T + dT/dP1 * (P1 - P2) - drho/dP1 * T g (z1 - z2) - dT/dP1 * rho g (z1 + // - z2) + dT/dP1 * (-Pc1 + Pc2) , + // -T + dT/dP2 * (P1 - P2) - drho/dP2 * T g (z1 - z2) - dT/dP2 * rho g (z1 + // - z2) + dT/dP2 * (-Pc1 + Pc2) } - dFlux_dS[ip][ke] += dCapGrad_dS[ip][ke]; // dF/dS = { T * -dPc/dS1 , T * dPc/dS2 } + dFlux_dS[ip][ke] += dCapGrad_dS[ip][ke]; // dF/dS = { T * -dPc/dS1 , T * dPc/dS2 } } } @@ -548,20 +561,25 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase for( integer ke = 0; ke < 2; ++ke ) { - dFlux_dP[ip][ke] *= mobility[ip]; // dF/dP = { M [ T + dT/dP1 * (P1 - P2) - drho/dP1 * T g (z1 - z2) - dT/dP1 * rho g (z1 - z2) + dT/dP1 * (-Pc1 + Pc2)] , - // M [-T + dT/dP2 * (P1 - P2) - drho/dP2 * T g (z1 - z2) - dT/dP2 * rho g (z1 - z2) + dT/dP2 * (-Pc1 + Pc2)] } + dFlux_dP[ip][ke] *= mobility[ip]; // dF/dP = { M [ T + dT/dP1 * (P1 - P2) - drho/dP1 * T g (z1 - z2) - dT/dP1 * rho g (z1 - + // z2) + dT/dP1 * (-Pc1 + Pc2)] , + // M [-T + dT/dP2 * (P1 - P2) - drho/dP2 * T g (z1 - z2) - dT/dP2 * rho g (z1 - + // z2) + dT/dP2 * (-Pc1 + Pc2)] } - dFlux_dS[ip][ke] *= mobility[ip]; // dF/dS = { M [T * -dPc/dS1] , M [T * dPc/dS2] } + dFlux_dS[ip][ke] *= mobility[ip]; // dF/dS = { M [T * -dPc/dS1] , M [T * dPc/dS2] } } // add contribution from upstream cell mobility derivatives for( integer ke = 0; ke < 2; ++ke ) { - dFlux_dP[ip][ke] += dMob_dP[ip][ke] * potGrad; // dF/dP = { M [ T + dT/dP1 * (P1 - P2) - drho1/dP * T g (z1 - z2) - dT/dP1 * rho g (z1 - z2) + dT/dP1 * (-Pc1 + Pc2)] + dM/dP1 * DPhi , - // M [-T + dT/dP2 * (P1 - P2) - drho2/dP * T g (z1 - z2) - dT/dP2 * rho g (z1 - z2) + dT/dP2 * (-Pc1 + Pc2)] + dM/dP2 * DPhi } + dFlux_dP[ip][ke] += dMob_dP[ip][ke] * potGrad; // dF/dP = { M [ T + dT/dP1 * (P1 - P2) - drho1/dP * T g (z1 - z2) - dT/dP1 * + // rho g (z1 - z2) + dT/dP1 * (-Pc1 + Pc2)] + dM/dP1 * DPhi , + // M [-T + dT/dP2 * (P1 - P2) - drho2/dP * T g (z1 - z2) - dT/dP2 * + // rho g (z1 - z2) + dT/dP2 * (-Pc1 + Pc2)] + dM/dP2 * DPhi } - dFlux_dS[ip][ke] += dMob_dS[ip][ke] * potGrad; // dF/dS = { M [T * -dPc/dS1] + dM/dS1 * DPhi , M [T * dPc/dS2] + dM/dS2 * DPhi } - } + dFlux_dS[ip][ke] += dMob_dS[ip][ke] * potGrad; // dF/dS = { M [T * -dPc/dS1] + dM/dS1 * DPhi , M [T * dPc/dS2] + dM/dS2 * DPhi + // } + } // populate local flux vector and derivatives stack.localFlux[k[0]*numEqn + ip] += m_dt * fluxVal[ip]; @@ -581,7 +599,8 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase } // Customize the kernel with this lambda - kernelOp( k, seri, sesri, sei, connectionIndex, alpha, mobility, potGrad, fluxVal, dFlux_dP, dFlux_dS ); // Not sure what this does + kernelOp( k, seri, sesri, sei, connectionIndex, alpha, mobility, potGrad, fluxVal, dFlux_dP, dFlux_dS ); // Not sure what this + // does } // loop over phases @@ -597,7 +616,7 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase */ template< typename FUNC = NoOpFunc > // should change to multiphase GEOS_HOST_DEVICE - void complete( localIndex const iconn, + void complete( localIndex const iconn, StackVariables & stack, FUNC && kernelOp = NoOpFunc{} ) const { @@ -611,8 +630,8 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase globalIndex const globalRow = m_dofNumber[m_seri( iconn, i )][m_sesri( iconn, i )][m_sei( iconn, i )]; localIndex const localRow = LvArray::integerConversion< localIndex >( globalRow - m_rankOffset ); GEOS_ASSERT_GE( localRow, 0 ); - - GEOS_ASSERT_GT( m_localMatrix.numRows(), localRow + numEqn - 1); + + GEOS_ASSERT_GT( m_localMatrix.numRows(), localRow + numEqn - 1 ); for( integer ic = 0; ic < numEqn; ++ic ) { @@ -623,7 +642,7 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase stack.dofColIndices.data(), stack.localFluxJacobian[i * numEqn + ic].dataIfContiguous(), stack.stencilSize * numDof ); - } + } // call the lambda to assemble additional terms, such as thermal terms kernelOp( i, localRow ); @@ -695,7 +714,7 @@ class FaceBasedAssemblyKernelFactory template< typename POLICY, typename STENCILWRAPPER > static void createAndLaunch( integer const numPhases, - globalIndex const rankOffset, + globalIndex const rankOffset, string const & dofKey, integer const hasCapPressure, integer const useTotalMassEquation, @@ -715,7 +734,7 @@ class FaceBasedAssemblyKernelFactory using kernelType = FaceBasedAssemblyKernel< NUM_EQN, NUM_DOF, STENCILWRAPPER >; typename kernelType::ImmiscibleMultiphaseFlowAccessors flowAccessors( elemManager, solverName ); - typename kernelType::MultiphaseFluidAccessors fluidAccessors( elemManager, solverName ); + typename kernelType::MultiphaseFluidAccessors fluidAccessors( elemManager, solverName ); typename kernelType::CapPressureAccessors capPressureAccessors( elemManager, solverName ); typename kernelType::PermeabilityAccessors permAccessors( elemManager, solverName ); @@ -738,7 +757,7 @@ class PhaseMobilityKernel { public: - //using Base = MultiphaseFluidAccessors::PropertyKernelBase< NUM_COMP >; + //using Base = MultiphaseFluidAccessors::PropertyKernelBase< NUM_COMP >; /// Compile time value for the number of phases static constexpr integer numPhase = NUM_PHASE; @@ -752,7 +771,7 @@ class PhaseMobilityKernel PhaseMobilityKernel( ObjectManagerBase & subRegion, TwoPhaseFluid const & fluid, RelativePermeabilityBase const & relperm ) - : + : m_phaseDens( fluid.phaseDensity() ), m_dPhaseDens( fluid.dPhaseDensity() ), m_phaseVisc( fluid.phaseViscosity() ), @@ -792,10 +811,10 @@ class PhaseMobilityKernel void compute( localIndex const ei, FUNC && phaseMobilityKernelOp = NoOpFunc{} ) const { - using Deriv = immiscibleFlow::DerivativeOffset; - + using Deriv = immiscibleFlow::DerivativeOffset; + arraySlice1d< real64, immiscibleFlow::USD_PHASE - 1 > const phaseMob = m_phaseMob[ei]; - arraySlice2d< real64, immiscibleFlow::USD_PHASE_DS - 1 > const dPhaseMob = m_dPhaseMob[ei]; + arraySlice2d< real64, immiscibleFlow::USD_PHASE_DS - 1 > const dPhaseMob = m_dPhaseMob[ei]; for( integer ip = 0; ip < numPhase; ++ip ) { @@ -804,18 +823,18 @@ class PhaseMobilityKernel real64 const viscosity = m_phaseVisc[ei][0][ip]; real64 const dVisc_dP = m_dPhaseVisc[ei][0][ip][Deriv::dP]; - real64 const relPerm = m_phaseRelPerm[ei][0][ip]; + real64 const relPerm = m_phaseRelPerm[ei][0][ip]; real64 const mobility = relPerm * density / viscosity; phaseMob[ip] = mobility; - dPhaseMob[ip][Deriv::dP] = mobility * (dDens_dP / density - dVisc_dP / viscosity); + dPhaseMob[ip][Deriv::dP] = mobility * (dDens_dP / density - dVisc_dP / viscosity); for( integer jp = 0; jp < numPhase-1; ++jp ) { - real64 const dRelPerm_dS = m_dPhaseRelPerm_dPhaseVolFrac[ei][0][ip][jp]; - dPhaseMob[ip][Deriv::dS+jp] = dRelPerm_dS * density / viscosity; - } + real64 const dRelPerm_dS = m_dPhaseRelPerm_dPhaseVolFrac[ei][0][ip][jp]; + dPhaseMob[ip][Deriv::dS+jp] = dRelPerm_dS * density / viscosity; + } // call the lambda in the phase loop to allow the reuse of the relperm, density, viscosity, and mobility // possible use: assemble the derivatives wrt temperature @@ -836,7 +855,7 @@ class PhaseMobilityKernel /// Views on the phase viscosities arrayView3d< real64 const, constitutive::multifluid::USD_PHASE > m_phaseVisc; - arrayView4d< real64 const, constitutive::multifluid::USD_PHASE_DC > m_dPhaseVisc; + arrayView4d< real64 const, constitutive::multifluid::USD_PHASE_DC > m_dPhaseVisc; //arrayView2d< real64 const, immiscibleFlow::USD_PHASE > m_phaseVisc; //arrayView2d< real64 const, immiscibleFlow::USD_PHASE > m_dPhaseVisc; @@ -856,7 +875,7 @@ class PhaseMobilityKernel */ class PhaseMobilityKernelFactory { -public: +public: /** * @brief Create a new kernel and launch @@ -873,7 +892,7 @@ class PhaseMobilityKernelFactory RelativePermeabilityBase const & relperm ) { if( numPhase == 2 ) - { + { PhaseMobilityKernel< 2 > kernel( subRegion, fluid, relperm ); PhaseMobilityKernel< 2 >::template launch< POLICY >( subRegion.size(), kernel ); } @@ -908,7 +927,7 @@ struct FluidUpdateKernel */ /// Compile time value for the number of norms to compute - static constexpr integer numNorm = 1; +static constexpr integer numNorm = 1; class ResidualNormKernel : public solverBaseKernels::ResidualNormKernelBase< numNorm > { @@ -919,9 +938,9 @@ class ResidualNormKernel : public solverBaseKernels::ResidualNormKernelBase< num using Base::m_minNormalizer; using Base::m_rankOffset; using Base::m_localResidual; - using Base::m_dofNumber; + using Base::m_dofNumber; -ResidualNormKernel( globalIndex const rankOffset, + ResidualNormKernel( globalIndex const rankOffset, arrayView1d< real64 const > const & localResidual, arrayView1d< globalIndex const > const & dofNumber, arrayView1d< localIndex const > const & ghostRank, @@ -962,7 +981,7 @@ ResidualNormKernel( globalIndex const rankOffset, { for( integer idof = 0; idof < m_numPhases; ++idof ) { - real64 const massNormalizer = LvArray::math::max( m_minNormalizer, m_phaseMass_n[ei][idof] ); + real64 const massNormalizer = LvArray::math::max( m_minNormalizer, m_phaseMass_n[ei][idof] ); stack.localValue[0] += m_localResidual[stack.localRow + idof] * m_localResidual[stack.localRow + idof]; stack.localNormalizer[0] += massNormalizer; } @@ -970,7 +989,7 @@ ResidualNormKernel( globalIndex const rankOffset, protected: - + /// Number of fluid phases integer const m_numPhases; @@ -1034,7 +1053,6 @@ class ResidualNormKernelFactory - } // namespace immiscible multiphasekernels From 6a43303cef12284216b16ddf4e881ab0d4a43531 Mon Sep 17 00:00:00 2001 From: Ammara-14 Date: Tue, 8 Oct 2024 12:19:17 -0700 Subject: [PATCH 039/102] Added applySystemSolution and phaseVolumeFractions boundary conditions --- .../fluidFlow/ImmiscibleMultiphaseFlow.cpp | 146 +++++++++++++++--- .../fluidFlow/ImmiscibleMultiphaseFlow.hpp | 7 + 2 files changed, 134 insertions(+), 19 deletions(-) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp index a0f0be788a2..b3ddad9207d 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp @@ -133,6 +133,9 @@ void ImmiscibleMultiphaseFlow::registerDataOnMesh( Group & meshBodies ) subRegion.registerField< phaseVolumeFraction_n >( getName() ). reference().resizeDimension< 1 >( m_numPhases ); + subRegion.registerField< bcPhaseVolumeFraction>( getName() ). + reference().resizeDimension< 1 >( m_numPhases ); + subRegion.registerField< phaseMass >( getName() ). reference().resizeDimension< 1 >( m_numPhases ); @@ -757,6 +760,69 @@ char const bcLogMessage[] = "\nNote that if this number is equal to zero for all subRegions, the boundary condition will not be applied on this element set."; } + +void applyAndSpecifyFieldValue( real64 const & time_n, + real64 const & dt, + MeshLevel & mesh, + globalIndex const rankOffset, + string const dofKey, + bool const, + integer const idof, + string const fieldKey, + string const boundaryFieldKey, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) +{ + FieldSpecificationManager & fsManager = FieldSpecificationManager::getInstance(); + + fsManager.apply< ElementSubRegionBase >( time_n + dt, + mesh, + fieldKey, + [&]( FieldSpecificationBase const & fs, + string const &, + SortedArrayView< localIndex const > const & lset, + ElementSubRegionBase & subRegion, + string const & ) + { + // Specify the bc value of the field + fs.applyFieldValue< FieldSpecificationEqual, + parallelDevicePolicy<> >( lset, + time_n + dt, + subRegion, + boundaryFieldKey ); + + arrayView1d< integer const > const ghostRank = subRegion.ghostRank(); + arrayView1d< globalIndex const > const dofNumber = + subRegion.getReference< array1d< globalIndex > >( dofKey ); + arrayView1d< real64 const > const bcField = + subRegion.getReference< array1d< real64 > >( boundaryFieldKey ); + arrayView1d< real64 const > const field = + subRegion.getReference< array1d< real64 > >( fieldKey ); + + forAll< parallelDevicePolicy<> >( lset.size(), [=] GEOS_HOST_DEVICE ( localIndex const a ) + { + localIndex const ei = lset[a]; + if( ghostRank[ei] >= 0 ) + { + return; + } + + globalIndex const dofIndex = dofNumber[ei]; + localIndex const localRow = dofIndex - rankOffset; + real64 rhsValue; + + // Apply field value to the matrix/rhs + FieldSpecificationEqual::SpecifyFieldValue( dofIndex + idof, + rankOffset, + localMatrix, + rhsValue, + bcField[ei], + field[ei] ); + localRhs[localRow + idof] = rhsValue; + } ); + } ); +} + void ImmiscibleMultiphaseFlow::applyDirichletBC( real64 const time_n, real64 const dt, DofManager const & dofManager, @@ -784,9 +850,9 @@ void ImmiscibleMultiphaseFlow::applyDirichletBC( real64 const time_n, applyFieldValue< ElementSubRegionBase >( time_n, dt, mesh, bcLogMessage, fields::flow::pressure::key(), fields::flow::bcPressure::key() ); // 2. Apply saturation BC (phase volume fraction) and store in a separate field - //applyFieldValue< ElementSubRegionBase >( time_n, dt, mesh, bcLogMessage, - // fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key(), - // fields::immiscibleMultiphaseFlow::bcPhaseVolumeFraction::key() ); + applyFieldValue< ElementSubRegionBase >( time_n, dt, mesh, bcLogMessage, + fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key(), + fields::immiscibleMultiphaseFlow::bcPhaseVolumeFraction::key() ); globalIndex const rankOffset = dofManager.rankOffset(); string const dofKey = dofManager.getKey( viewKeyStruct::elemDofFieldString() ); @@ -804,9 +870,9 @@ void ImmiscibleMultiphaseFlow::applyDirichletBC( real64 const time_n, arrayView1d< real64 const > const bcPres = subRegion.getReference< array1d< real64 > >( fields::flow::bcPressure::key() ); - //arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const bcPhaseVolFraction = - //subRegion.getReference< array2d< real64, immiscibleFlow::LAYOUT_PHASE > >( - // fields::immiscibleMultiphaseFlow::bcPhaseVolumeFraction::key() ); + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const bcPhaseVolFraction = + subRegion.getReference< array2d< real64, immiscibleFlow::LAYOUT_PHASE > >( + fields::immiscibleMultiphaseFlow::bcPhaseVolumeFraction::key() ); arrayView1d< integer const > const ghostRank = subRegion.getReference< array1d< integer > >( ObjectManagerBase::viewKeyStruct::ghostRankString() ); @@ -814,9 +880,9 @@ void ImmiscibleMultiphaseFlow::applyDirichletBC( real64 const time_n, subRegion.getReference< array1d< globalIndex > >( dofKey ); arrayView1d< real64 const > const pres = subRegion.getReference< array1d< real64 > >( fields::flow::pressure::key() ); - //arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFraction = - //subRegion.getReference< array2d< real64, immiscibleFlow::LAYOUT_PHASE > >( - // fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key() ); + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFraction = + subRegion.getReference< array2d< real64, immiscibleFlow::LAYOUT_PHASE > >( + fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key() ); integer const numPhase = m_numPhases; forAll< parallelDevicePolicy<> >( targetSet.size(), [=] GEOS_HOST_DEVICE ( localIndex const a ) @@ -841,16 +907,16 @@ void ImmiscibleMultiphaseFlow::applyDirichletBC( real64 const time_n, localRhs[localRow] = rhsValue; // 3.2. For each phase, apply target saturation value - // for( integer ip = 0; ip < numPhase; ++ip ) - // { - // FieldSpecificationEqual::SpecifyFieldValue( dofIndex + ip + 1, - // rankOffset, - // localMatrix, - // rhsValue, - // bcPhaseVolFraction[ei][ip], - // phaseVolFraction[ei][ip] ); - // localRhs[localRow + ip + 1] = rhsValue; - // } + for( integer ip = 0; ip < numPhase-1; ++ip ) + { + FieldSpecificationEqual::SpecifyFieldValue( dofIndex + ip + 1, + rankOffset, + localMatrix, + rhsValue, + bcPhaseVolFraction[ei][ip], + phaseVolFraction[ei][ip] ); + localRhs[localRow + ip + 1] = rhsValue; + } } ); } ); } ); @@ -944,6 +1010,48 @@ real64 ImmiscibleMultiphaseFlow::calculateResidualNorm( real64 const & GEOS_UNUS return residualNorm; } +void ImmiscibleMultiphaseFlow::applySystemSolution( DofManager const & dofManager, + arrayView1d< real64 const > const & localSolution, + real64 const scalingFactor, + real64 const dt, + DomainPartition & domain ) +{ + GEOS_UNUSED_VAR( dt ); + + DofManager::CompMask pressureMask( m_numDofPerCell, 0, 1 ); + DofManager::CompMask PhaseMask( m_numDofPerCell, 1, m_numPhases ); + + // 1. apply the pressure update + + dofManager.addVectorToField( localSolution, + viewKeyStruct::elemDofFieldString(), + fields::flow::pressure::key(), + scalingFactor, + pressureMask ); + + // 2. apply the phaseVolumeFraction update + + dofManager.addVectorToField( localSolution, + viewKeyStruct::elemDofFieldString(), + fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key(), + scalingFactor, + PhaseMask ); + + // 3. synchronize + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&] ( string const &, + MeshLevel & mesh, + arrayView1d< string const > const & regionNames ) + { + std::vector< string > fields{ fields::flow::pressure::key(), fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key() }; + + FieldIdentifiers fieldsToBeSync; + fieldsToBeSync.addElementFields( fields, regionNames ); + + CommunicationTools::getInstance().synchronizeFields( fieldsToBeSync, mesh, domain.getNeighbors(), true ); + } ); +} + + void ImmiscibleMultiphaseFlow::resetStateToBeginningOfStep( DomainPartition & domain ) { GEOS_MARK_FUNCTION; diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp index 65961ec2df8..a5b0ccdf809 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp @@ -96,6 +96,13 @@ class ImmiscibleMultiphaseFlow : public FlowSolverBase DofManager const & dofManager, arrayView1d< real64 const > const & localRhs ) override; + virtual void + applySystemSolution( DofManager const & dofManager, + arrayView1d< real64 const > const & localSolution, + real64 const scalingFactor, + real64 const dt, + DomainPartition & domain ) override; + virtual void setupDofs( DomainPartition const & domain, DofManager & dofManager ) const override; From c854b703df5b697baa42b4b97673696f86ea352f Mon Sep 17 00:00:00 2001 From: Ammara-14 Date: Wed, 16 Oct 2024 10:19:17 -0700 Subject: [PATCH 040/102] this version runs a simple test case with no convergence issues --- .../fluidFlow/ImmiscibleMultiphaseFlow.cpp | 57 +++++++++++++++++-- .../fluidFlow/ImmiscibleMultiphaseFlow.hpp | 2 + .../fluidFlow/ImmiscibleMultiphaseKernels.hpp | 17 +++++- 3 files changed, 70 insertions(+), 6 deletions(-) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp index b3ddad9207d..cc1191e0fa3 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp @@ -284,6 +284,7 @@ void ImmiscibleMultiphaseFlow::updateFluidState( ElementSubRegionBase & subRegio GEOS_MARK_FUNCTION; updateFluidModel( subRegion ); + updatePhaseVolumeFraction( subRegion ); updatePhaseMass( subRegion ); updateRelPermModel( subRegion ); updatePhaseMobility( subRegion ); @@ -529,6 +530,7 @@ ImmiscibleMultiphaseFlow::implicitStepSetup( real64 const & GEOS_UNUSED_PARAM( t // update porosity, permeability updatePorosityAndPermeability( subRegion ); // update all fluid properties + updatePhaseVolumeFraction( subRegion ); updateFluidState( subRegion ); // after the update, save the new saturation @@ -639,7 +641,7 @@ void ImmiscibleMultiphaseFlow::assembleAccumulationTerm( DomainPartition & domai } // compute accumulation - + int signPotDiff[2] = {1, -1}; for( integer ip = 0; ip < numofPhases; ++ip ) { @@ -653,8 +655,17 @@ void ImmiscibleMultiphaseFlow::assembleAccumulationTerm( DomainPartition & domai localJacobian[ip][0] += dPhaseMass_dP; real64 const dPhaseMass_dS = poreVolume * phaseDens[ei][0][ip]; + + + // if ( ip == 0) + // { + // localJacobian[ip][1] += dPhaseMass_dS; + // } else { + // localJacobian[ip][1] -= dPhaseMass_dS; + // } + + localJacobian[ip][1] += signPotDiff[ip] * dPhaseMass_dS; - localJacobian[ip][1] += dPhaseMass_dS; } // complete @@ -745,9 +756,17 @@ void ImmiscibleMultiphaseFlow::applyBoundaryConditions( real64 const time_n, arrayView1d< real64 > const & localRhs ) { GEOS_MARK_FUNCTION; - + // apply pressure boundary conditions. applyDirichletBC( time_n, dt, dofManager, domain, localMatrix.toViewConstSizes(), localRhs.toView() ); + + // for( localIndex row = 0; row < localMatrix.toViewConstSizes().numRows(); ++row ) + // { + // std::cout << "row " << row << std::endl; + // std::cout << "\tcolumns: " << localMatrix.toViewConstSizes().getColumns( row ) << std::endl; + // std::cout << "\tvalues: " << localMatrix.toViewConstSizes().getEntries( row ) << std::endl; + // } + } namespace @@ -884,7 +903,11 @@ void ImmiscibleMultiphaseFlow::applyDirichletBC( real64 const time_n, subRegion.getReference< array2d< real64, immiscibleFlow::LAYOUT_PHASE > >( fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key() ); + // GEOS_LOG_RANK_0(GEOS_FMT("Saturation {}", phaseVolFraction)); + integer const numPhase = m_numPhases; + + forAll< parallelDevicePolicy<> >( targetSet.size(), [=] GEOS_HOST_DEVICE ( localIndex const a ) { localIndex const ei = targetSet[a]; @@ -905,6 +928,8 @@ void ImmiscibleMultiphaseFlow::applyDirichletBC( real64 const time_n, bcPres[ei], pres[ei] ); localRhs[localRow] = rhsValue; + // GEOS_LOG_RANK_0(GEOS_FMT("BC Pressure {}", bcPres[ei])); + // GEOS_LOG_RANK_0(GEOS_FMT("Pressure {}", pres[ei])); // 3.2. For each phase, apply target saturation value for( integer ip = 0; ip < numPhase-1; ++ip ) @@ -916,12 +941,16 @@ void ImmiscibleMultiphaseFlow::applyDirichletBC( real64 const time_n, bcPhaseVolFraction[ei][ip], phaseVolFraction[ei][ip] ); localRhs[localRow + ip + 1] = rhsValue; + + // GEOS_LOG_RANK_0(GEOS_FMT("BC Saturation {}", bcPhaseVolFraction[ei][ip])); + // GEOS_LOG_RANK_0(GEOS_FMT("Saturation {}", phaseVolFraction[ei][ip])); } } ); } ); } ); } + real64 ImmiscibleMultiphaseFlow::calculateResidualNorm( real64 const & GEOS_UNUSED_PARAM( time_n ), real64 const & GEOS_UNUSED_PARAM( dt ), DomainPartition const & domain, @@ -1019,7 +1048,7 @@ void ImmiscibleMultiphaseFlow::applySystemSolution( DofManager const & dofManage GEOS_UNUSED_VAR( dt ); DofManager::CompMask pressureMask( m_numDofPerCell, 0, 1 ); - DofManager::CompMask PhaseMask( m_numDofPerCell, 1, m_numPhases ); + //DofManager::CompMask PhaseMask( m_numDofPerCell, 1, m_numPhases ); // 1. apply the pressure update @@ -1035,7 +1064,7 @@ void ImmiscibleMultiphaseFlow::applySystemSolution( DofManager const & dofManage viewKeyStruct::elemDofFieldString(), fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key(), scalingFactor, - PhaseMask ); + ~pressureMask ); // 3. synchronize forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&] ( string const &, @@ -1049,9 +1078,26 @@ void ImmiscibleMultiphaseFlow::applySystemSolution( DofManager const & dofManage CommunicationTools::getInstance().synchronizeFields( fieldsToBeSync, mesh, domain.getNeighbors(), true ); } ); + } +void ImmiscibleMultiphaseFlow::updatePhaseVolumeFraction( ElementSubRegionBase & subRegion ) const +{ + GEOS_MARK_FUNCTION; + integer const numofPhases = 2; + + //arrayView1d< real64 const> const singleSaturation = subRegion.getField< fields::immiscibleMultiphaseFlow::singleSaturation >(); + arrayView2d< real64, immiscibleFlow::USD_PHASE > const phaseVolumeFraction = subRegion.getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); + + forAll< parallelDevicePolicy<> >( subRegion.size(), [=] GEOS_HOST_DEVICE ( localIndex const ei ) + { + // phaseVolumeFraction[ei][0] = singleSaturation[ei]; + phaseVolumeFraction[ei][1] = 1.0 - phaseVolumeFraction[ei][0]; + } + ); +} + void ImmiscibleMultiphaseFlow::resetStateToBeginningOfStep( DomainPartition & domain ) { GEOS_MARK_FUNCTION; @@ -1193,6 +1239,7 @@ void ImmiscibleMultiphaseFlow::updateState( DomainPartition & domain ) // update porosity, permeability, and solid internal energy updatePorosityAndPermeability( subRegion ); // update all fluid properties + updatePhaseVolumeFraction( subRegion ); updateFluidState( subRegion ); } ); } ); diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp index a5b0ccdf809..0e95c760cea 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp @@ -125,6 +125,8 @@ class ImmiscibleMultiphaseFlow : public FlowSolverBase void updateFluidState( ElementSubRegionBase & subRegion ) const; + void updatePhaseVolumeFraction( ElementSubRegionBase & subRegion ) const; + virtual void saveConvergedState( ElementSubRegionBase & subRegion ) const override final; virtual void updateState( DomainPartition & domain ) override final; diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseKernels.hpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseKernels.hpp index 97690653236..7bbcd75004e 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseKernels.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseKernels.hpp @@ -963,15 +963,30 @@ class ResidualNormKernel : public solverBaseKernels::ResidualNormKernelBase< num virtual void computeLinf( localIndex const ei, LinfStackVariables & stack ) const override { + real64 massNormalizer = 0; + for( integer idof = 0; idof < m_numPhases; ++idof ) + { + massNormalizer += LvArray::math::max( m_minNormalizer, m_phaseMass_n[ei][idof] ); + } + for( integer idof = 0; idof < m_numPhases; ++idof ) { - real64 const massNormalizer = LvArray::math::max( m_minNormalizer, m_phaseMass_n[ei][idof] ); real64 const valMass = LvArray::math::abs( m_localResidual[stack.localRow + idof] ) / massNormalizer; if( valMass > stack.localValue[0] ) { stack.localValue[0] = valMass; } } + + // for( integer idof = 0; idof < m_numPhases; ++idof ) + // { + // real64 const massNormalizer = LvArray::math::max( m_minNormalizer, m_phaseMass_n[ei][idof] ); + // real64 const valMass = LvArray::math::abs( m_localResidual[stack.localRow + idof] ) / massNormalizer; + // if( valMass > stack.localValue[0] ) + // { + // stack.localValue[0] = valMass; + // } + // } } From f4be6ef0ad8b3d3fb4df6f05bc23b856f57cc287 Mon Sep 17 00:00:00 2001 From: Ammara-14 Date: Thu, 17 Oct 2024 12:34:36 -0700 Subject: [PATCH 041/102] Fixed relative permeability calculation --- .../fluidFlow/ImmiscibleMultiphaseKernels.hpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseKernels.hpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseKernels.hpp index 7bbcd75004e..4f98986dd75 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseKernels.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseKernels.hpp @@ -815,6 +815,7 @@ class PhaseMobilityKernel arraySlice1d< real64, immiscibleFlow::USD_PHASE - 1 > const phaseMob = m_phaseMob[ei]; arraySlice2d< real64, immiscibleFlow::USD_PHASE_DS - 1 > const dPhaseMob = m_dPhaseMob[ei]; + int sign[2] = {1, -1}; for( integer ip = 0; ip < numPhase; ++ip ) { @@ -830,11 +831,11 @@ class PhaseMobilityKernel phaseMob[ip] = mobility; dPhaseMob[ip][Deriv::dP] = mobility * (dDens_dP / density - dVisc_dP / viscosity); - for( integer jp = 0; jp < numPhase-1; ++jp ) - { - real64 const dRelPerm_dS = m_dPhaseRelPerm_dPhaseVolFrac[ei][0][ip][jp]; - dPhaseMob[ip][Deriv::dS+jp] = dRelPerm_dS * density / viscosity; - } + // for( integer jp = 0; jp < numPhase-1; ++jp ) + // { + real64 const dRelPerm_dS = sign[ip] * m_dPhaseRelPerm_dPhaseVolFrac[ei][0][ip][ip]; + dPhaseMob[ip][Deriv::dS] = dRelPerm_dS * density / viscosity; + // } // call the lambda in the phase loop to allow the reuse of the relperm, density, viscosity, and mobility // possible use: assemble the derivatives wrt temperature From 2acd7c99ea42d63bf4ab9af2f0f17001691242ec Mon Sep 17 00:00:00 2001 From: DENEL Bertrand Date: Thu, 17 Oct 2024 17:09:37 -0500 Subject: [PATCH 042/102] Clean up and formatting. --- .../fluidFlow/ImmiscibleMultiphaseFlow.cpp | 71 +++++++++---------- .../fluidFlow/ImmiscibleMultiphaseKernels.hpp | 16 ++--- 2 files changed, 40 insertions(+), 47 deletions(-) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp index cc1191e0fa3..0a1429ef807 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp @@ -133,7 +133,7 @@ void ImmiscibleMultiphaseFlow::registerDataOnMesh( Group & meshBodies ) subRegion.registerField< phaseVolumeFraction_n >( getName() ). reference().resizeDimension< 1 >( m_numPhases ); - subRegion.registerField< bcPhaseVolumeFraction>( getName() ). + subRegion.registerField< bcPhaseVolumeFraction >( getName() ). reference().resizeDimension< 1 >( m_numPhases ); subRegion.registerField< phaseMass >( getName() ). @@ -302,7 +302,6 @@ void ImmiscibleMultiphaseFlow::updatePhaseMass( ElementSubRegionBase & subRegion TwoPhaseFluid const & fluid = getConstitutiveModel< TwoPhaseFluid >( subRegion, fluidName ); CoupledSolidBase const & solid = getConstitutiveModel< CoupledSolidBase >( subRegion, solidName ); - integer const numofPhases = 2; arrayView1d< real64 const > const volume = subRegion.getElementVolume(); arrayView2d< real64 const > const porosity = solid.getPorosity(); @@ -655,8 +654,8 @@ void ImmiscibleMultiphaseFlow::assembleAccumulationTerm( DomainPartition & domai localJacobian[ip][0] += dPhaseMass_dP; real64 const dPhaseMass_dS = poreVolume * phaseDens[ei][0][ip]; - - + + // if ( ip == 0) // { // localJacobian[ip][1] += dPhaseMass_dS; @@ -756,7 +755,7 @@ void ImmiscibleMultiphaseFlow::applyBoundaryConditions( real64 const time_n, arrayView1d< real64 > const & localRhs ) { GEOS_MARK_FUNCTION; - + // apply pressure boundary conditions. applyDirichletBC( time_n, dt, dofManager, domain, localMatrix.toViewConstSizes(), localRhs.toView() ); @@ -871,7 +870,7 @@ void ImmiscibleMultiphaseFlow::applyDirichletBC( real64 const time_n, // 2. Apply saturation BC (phase volume fraction) and store in a separate field applyFieldValue< ElementSubRegionBase >( time_n, dt, mesh, bcLogMessage, fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key(), - fields::immiscibleMultiphaseFlow::bcPhaseVolumeFraction::key() ); + fields::immiscibleMultiphaseFlow::bcPhaseVolumeFraction::key() ); globalIndex const rankOffset = dofManager.rankOffset(); string const dofKey = dofManager.getKey( viewKeyStruct::elemDofFieldString() ); @@ -890,8 +889,8 @@ void ImmiscibleMultiphaseFlow::applyDirichletBC( real64 const time_n, arrayView1d< real64 const > const bcPres = subRegion.getReference< array1d< real64 > >( fields::flow::bcPressure::key() ); arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const bcPhaseVolFraction = - subRegion.getReference< array2d< real64, immiscibleFlow::LAYOUT_PHASE > >( - fields::immiscibleMultiphaseFlow::bcPhaseVolumeFraction::key() ); + subRegion.getReference< array2d< real64, immiscibleFlow::LAYOUT_PHASE > >( + fields::immiscibleMultiphaseFlow::bcPhaseVolumeFraction::key() ); arrayView1d< integer const > const ghostRank = subRegion.getReference< array1d< integer > >( ObjectManagerBase::viewKeyStruct::ghostRankString() ); @@ -900,10 +899,10 @@ void ImmiscibleMultiphaseFlow::applyDirichletBC( real64 const time_n, arrayView1d< real64 const > const pres = subRegion.getReference< array1d< real64 > >( fields::flow::pressure::key() ); arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFraction = - subRegion.getReference< array2d< real64, immiscibleFlow::LAYOUT_PHASE > >( - fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key() ); + subRegion.getReference< array2d< real64, immiscibleFlow::LAYOUT_PHASE > >( + fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key() ); - // GEOS_LOG_RANK_0(GEOS_FMT("Saturation {}", phaseVolFraction)); + // GEOS_LOG_RANK_0(GEOS_FMT("Saturation {}", phaseVolFraction)); integer const numPhase = m_numPhases; @@ -928,8 +927,8 @@ void ImmiscibleMultiphaseFlow::applyDirichletBC( real64 const time_n, bcPres[ei], pres[ei] ); localRhs[localRow] = rhsValue; - // GEOS_LOG_RANK_0(GEOS_FMT("BC Pressure {}", bcPres[ei])); - // GEOS_LOG_RANK_0(GEOS_FMT("Pressure {}", pres[ei])); + // GEOS_LOG_RANK_0(GEOS_FMT("BC Pressure {}", bcPres[ei])); + // GEOS_LOG_RANK_0(GEOS_FMT("Pressure {}", pres[ei])); // 3.2. For each phase, apply target saturation value for( integer ip = 0; ip < numPhase-1; ++ip ) @@ -942,8 +941,8 @@ void ImmiscibleMultiphaseFlow::applyDirichletBC( real64 const time_n, phaseVolFraction[ei][ip] ); localRhs[localRow + ip + 1] = rhsValue; - // GEOS_LOG_RANK_0(GEOS_FMT("BC Saturation {}", bcPhaseVolFraction[ei][ip])); - // GEOS_LOG_RANK_0(GEOS_FMT("Saturation {}", phaseVolFraction[ei][ip])); + // GEOS_LOG_RANK_0(GEOS_FMT("BC Saturation {}", bcPhaseVolFraction[ei][ip])); + // GEOS_LOG_RANK_0(GEOS_FMT("Saturation {}", phaseVolFraction[ei][ip])); } } ); } ); @@ -980,9 +979,6 @@ real64 ImmiscibleMultiphaseFlow::calculateResidualNorm( real64 const & GEOS_UNUS real64 subRegionResidualNorm[numNorm]{}; real64 subRegionResidualNormalizer[numNorm]{}; - string const & fluidName = subRegion.getReference< string >( viewKeyStruct::fluidNamesString() ); - TwoPhaseFluid const & fluid = getConstitutiveModel< TwoPhaseFluid >( subRegion, fluidName ); - string const & solidName = subRegion.getReference< string >( viewKeyStruct::solidNamesString() ); CoupledSolidBase const & solid = getConstitutiveModel< CoupledSolidBase >( subRegion, solidName ); @@ -1040,10 +1036,10 @@ real64 ImmiscibleMultiphaseFlow::calculateResidualNorm( real64 const & GEOS_UNUS } void ImmiscibleMultiphaseFlow::applySystemSolution( DofManager const & dofManager, - arrayView1d< real64 const > const & localSolution, - real64 const scalingFactor, - real64 const dt, - DomainPartition & domain ) + arrayView1d< real64 const > const & localSolution, + real64 const scalingFactor, + real64 const dt, + DomainPartition & domain ) { GEOS_UNUSED_VAR( dt ); @@ -1053,18 +1049,18 @@ void ImmiscibleMultiphaseFlow::applySystemSolution( DofManager const & dofManage // 1. apply the pressure update dofManager.addVectorToField( localSolution, - viewKeyStruct::elemDofFieldString(), - fields::flow::pressure::key(), - scalingFactor, - pressureMask ); + viewKeyStruct::elemDofFieldString(), + fields::flow::pressure::key(), + scalingFactor, + pressureMask ); // 2. apply the phaseVolumeFraction update dofManager.addVectorToField( localSolution, - viewKeyStruct::elemDofFieldString(), - fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key(), - scalingFactor, - ~pressureMask ); + viewKeyStruct::elemDofFieldString(), + fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key(), + scalingFactor, + ~pressureMask ); // 3. synchronize forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&] ( string const &, @@ -1085,18 +1081,15 @@ void ImmiscibleMultiphaseFlow::applySystemSolution( DofManager const & dofManage void ImmiscibleMultiphaseFlow::updatePhaseVolumeFraction( ElementSubRegionBase & subRegion ) const { GEOS_MARK_FUNCTION; - integer const numofPhases = 2; - - //arrayView1d< real64 const> const singleSaturation = subRegion.getField< fields::immiscibleMultiphaseFlow::singleSaturation >(); + arrayView2d< real64, immiscibleFlow::USD_PHASE > const phaseVolumeFraction = subRegion.getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); - + forAll< parallelDevicePolicy<> >( subRegion.size(), [=] GEOS_HOST_DEVICE ( localIndex const ei ) { - // phaseVolumeFraction[ei][0] = singleSaturation[ei]; - phaseVolumeFraction[ei][1] = 1.0 - phaseVolumeFraction[ei][0]; - } - ); -} + phaseVolumeFraction[ei][1] = 1.0 - phaseVolumeFraction[ei][0]; + } ); +} + void ImmiscibleMultiphaseFlow::resetStateToBeginningOfStep( DomainPartition & domain ) { diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseKernels.hpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseKernels.hpp index 4f98986dd75..0f668592462 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseKernels.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseKernels.hpp @@ -831,10 +831,10 @@ class PhaseMobilityKernel phaseMob[ip] = mobility; dPhaseMob[ip][Deriv::dP] = mobility * (dDens_dP / density - dVisc_dP / viscosity); - // for( integer jp = 0; jp < numPhase-1; ++jp ) - // { - real64 const dRelPerm_dS = sign[ip] * m_dPhaseRelPerm_dPhaseVolFrac[ei][0][ip][ip]; - dPhaseMob[ip][Deriv::dS] = dRelPerm_dS * density / viscosity; + // for( integer jp = 0; jp < numPhase-1; ++jp ) + // { + real64 const dRelPerm_dS = sign[ip] * m_dPhaseRelPerm_dPhaseVolFrac[ei][0][ip][ip]; + dPhaseMob[ip][Deriv::dS] = dRelPerm_dS * density / viscosity; // } // call the lambda in the phase loop to allow the reuse of the relperm, density, viscosity, and mobility @@ -965,10 +965,10 @@ class ResidualNormKernel : public solverBaseKernels::ResidualNormKernelBase< num LinfStackVariables & stack ) const override { real64 massNormalizer = 0; - for( integer idof = 0; idof < m_numPhases; ++idof ) + for( integer idof = 0; idof < m_numPhases; ++idof ) { - massNormalizer += LvArray::math::max( m_minNormalizer, m_phaseMass_n[ei][idof] ); - } + massNormalizer += LvArray::math::max( m_minNormalizer, m_phaseMass_n[ei][idof] ); + } for( integer idof = 0; idof < m_numPhases; ++idof ) { @@ -978,7 +978,7 @@ class ResidualNormKernel : public solverBaseKernels::ResidualNormKernelBase< num stack.localValue[0] = valMass; } } - + // for( integer idof = 0; idof < m_numPhases; ++idof ) // { // real64 const massNormalizer = LvArray::math::max( m_minNormalizer, m_phaseMass_n[ei][idof] ); From 7089df709532f5c3ad1d10863effde3073e204f3 Mon Sep 17 00:00:00 2001 From: DENEL Bertrand Date: Fri, 18 Oct 2024 12:37:25 -0500 Subject: [PATCH 043/102] Fixed GPU compilation. --- .../fluidFlow/ImmiscibleMultiphaseFlow.cpp | 8 -------- .../fluidFlow/ImmiscibleMultiphaseFlow.hpp | 12 ++++++------ 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp index 0a1429ef807..c18af502abc 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp @@ -902,8 +902,6 @@ void ImmiscibleMultiphaseFlow::applyDirichletBC( real64 const time_n, subRegion.getReference< array2d< real64, immiscibleFlow::LAYOUT_PHASE > >( fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key() ); - // GEOS_LOG_RANK_0(GEOS_FMT("Saturation {}", phaseVolFraction)); - integer const numPhase = m_numPhases; @@ -927,8 +925,6 @@ void ImmiscibleMultiphaseFlow::applyDirichletBC( real64 const time_n, bcPres[ei], pres[ei] ); localRhs[localRow] = rhsValue; - // GEOS_LOG_RANK_0(GEOS_FMT("BC Pressure {}", bcPres[ei])); - // GEOS_LOG_RANK_0(GEOS_FMT("Pressure {}", pres[ei])); // 3.2. For each phase, apply target saturation value for( integer ip = 0; ip < numPhase-1; ++ip ) @@ -940,9 +936,6 @@ void ImmiscibleMultiphaseFlow::applyDirichletBC( real64 const time_n, bcPhaseVolFraction[ei][ip], phaseVolFraction[ei][ip] ); localRhs[localRow + ip + 1] = rhsValue; - - // GEOS_LOG_RANK_0(GEOS_FMT("BC Saturation {}", bcPhaseVolFraction[ei][ip])); - // GEOS_LOG_RANK_0(GEOS_FMT("Saturation {}", phaseVolFraction[ei][ip])); } } ); } ); @@ -957,7 +950,6 @@ real64 ImmiscibleMultiphaseFlow::calculateResidualNorm( real64 const & GEOS_UNUS arrayView1d< real64 const > const & localRhs ) { GEOS_MARK_FUNCTION; - integer constexpr numNorm = 1; // mass balance array1d< real64 > localResidualNorm; array1d< real64 > localResidualNormalizer; localResidualNorm.resize( numNorm ); diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp index 0e95c760cea..47f450594d9 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp @@ -203,6 +203,12 @@ class ImmiscibleMultiphaseFlow : public FlowSolverBase virtual void initializePostInitialConditionsPreSubGroups() override; + /** + * @brief Function to update fluid mass + * @param subRegion subregion that contains the fields + */ + void updatePhaseMass( ElementSubRegionBase & subRegion ) const; + private: virtual void postInputInitialization() override; @@ -215,12 +221,6 @@ class ImmiscibleMultiphaseFlow : public FlowSolverBase */ void updateFluidModel( ObjectManagerBase & dataGroup ) const; - /** - * @brief Function to update fluid mass - * @param subRegion subregion that contains the fields - */ - void updatePhaseMass( ElementSubRegionBase & subRegion ) const; - /** * @brief Update all relevant relperm models using current values of phase volume fraction * @param dataGroup the group storing the required fields From 4418aaa065b30fd019c11db6ab205bbb601b953a Mon Sep 17 00:00:00 2001 From: DENEL Bertrand Date: Fri, 18 Oct 2024 16:08:39 -0500 Subject: [PATCH 044/102] Minor formatting to pass the CI uncrustify test --- .../physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp | 2 +- .../unitTests/constitutiveTests/testTwoPhaseFluid.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp index 47f450594d9..f5859062729 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp @@ -207,7 +207,7 @@ class ImmiscibleMultiphaseFlow : public FlowSolverBase * @brief Function to update fluid mass * @param subRegion subregion that contains the fields */ - void updatePhaseMass( ElementSubRegionBase & subRegion ) const; + void updatePhaseMass( ElementSubRegionBase & subRegion ) const; private: diff --git a/src/coreComponents/unitTests/constitutiveTests/testTwoPhaseFluid.cpp b/src/coreComponents/unitTests/constitutiveTests/testTwoPhaseFluid.cpp index ef37ec0cb13..b37fc732a55 100644 --- a/src/coreComponents/unitTests/constitutiveTests/testTwoPhaseFluid.cpp +++ b/src/coreComponents/unitTests/constitutiveTests/testTwoPhaseFluid.cpp @@ -99,7 +99,7 @@ class TwoPhaseFluidTest : public ConstitutiveTestBase< TwoPhaseFluid > fluidCopy.allocateConstitutiveData( fluid.getParent(), 1 ); // extract data views from both fluids -#define GET_FLUID_DATA( FLUID, TRAIT ) \ + #define GET_FLUID_DATA( FLUID, TRAIT ) \ FLUID.getReference< TRAIT::type >( TRAIT::key() )[0][0] constitutive::MultiFluidVarSlice< real64, 1, constitutive::multifluid::USD_PHASE - 2, constitutive::multifluid::USD_PHASE_DC - 2 > phaseVisc { From 61c61698480620c2be9e28c87e1df427aa8463ac Mon Sep 17 00:00:00 2001 From: DENEL Bertrand Date: Wed, 23 Oct 2024 16:42:32 -0500 Subject: [PATCH 045/102] Fixed reset function for saturations --- .../physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp index c18af502abc..e941b4a376b 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp @@ -1108,7 +1108,7 @@ void ImmiscibleMultiphaseFlow::resetStateToBeginningOfStep( DomainPartition & do arrayView2d< real64, immiscibleFlow::USD_PHASE > const phaseVolFrac = subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); - phaseVolFrac.setValues< parallelDevicePolicy<> >( phaseVolFrac ); + phaseVolFrac.setValues< parallelDevicePolicy<> >( phaseVolFrac_n ); arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const & phaseMass_n = subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseMass_n >(); From b8eafc336ad1f80707b001b7dd46275ba0c30684 Mon Sep 17 00:00:00 2001 From: DENEL Bertrand Date: Wed, 23 Oct 2024 19:16:28 -0500 Subject: [PATCH 046/102] Added a unit test to numerically check the Jacobian. --- .../fluidFlow/ImmiscibleMultiphaseFlow.hpp | 15 +- .../unitTests/fluidFlowTests/CMakeLists.txt | 3 +- .../testImmiscibleMultiphaseFlow.cpp | 448 ++++++++++++++++++ 3 files changed, 459 insertions(+), 7 deletions(-) create mode 100644 src/coreComponents/unitTests/fluidFlowTests/testImmiscibleMultiphaseFlow.cpp diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp index f5859062729..8abacdc7145 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp @@ -209,6 +209,14 @@ class ImmiscibleMultiphaseFlow : public FlowSolverBase */ void updatePhaseMass( ElementSubRegionBase & subRegion ) const; + struct viewKeyStruct : public FlowSolverBase::viewKeyStruct + { + static constexpr char const * capPressureNamesString() { return "capPressureNames"; } + static constexpr char const * relPermNamesString() { return "relPermNames"; } + static constexpr char const * elemDofFieldString() { return "elemDofField"; } + }; + + private: virtual void postInputInitialization() override; @@ -265,12 +273,7 @@ class ImmiscibleMultiphaseFlow : public FlowSolverBase /// flag to determine whether or not to use total velocity formulation integer m_useTotalMassEquation; - struct viewKeyStruct : public FlowSolverBase::viewKeyStruct - { - static constexpr char const * capPressureNamesString() { return "capPressureNames"; } - static constexpr char const * relPermNamesString() { return "relPermNames"; } - static constexpr char const * elemDofFieldString() { return "elemDofField"; } - }; + private: diff --git a/src/coreComponents/unitTests/fluidFlowTests/CMakeLists.txt b/src/coreComponents/unitTests/fluidFlowTests/CMakeLists.txt index c21190560cf..0663d3ad720 100644 --- a/src/coreComponents/unitTests/fluidFlowTests/CMakeLists.txt +++ b/src/coreComponents/unitTests/fluidFlowTests/CMakeLists.txt @@ -4,7 +4,8 @@ set( gtest_geosx_tests testThermalCompMultiphaseFlow.cpp testThermalSinglePhaseFlow.cpp testFlowStatistics.cpp - testTransmissibility.cpp ) + testTransmissibility.cpp + testImmiscibleMultiphaseFlow.cpp ) if( ENABLE_PVTPackage ) list( APPEND gtest_geosx_tests diff --git a/src/coreComponents/unitTests/fluidFlowTests/testImmiscibleMultiphaseFlow.cpp b/src/coreComponents/unitTests/fluidFlowTests/testImmiscibleMultiphaseFlow.cpp new file mode 100644 index 00000000000..9e2c4cc4b06 --- /dev/null +++ b/src/coreComponents/unitTests/fluidFlowTests/testImmiscibleMultiphaseFlow.cpp @@ -0,0 +1,448 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * SPDX-License-Identifier: LGPL-2.1-only + * + * Copyright (c) 2016-2024 Lawrence Livermore National Security LLC + * Copyright (c) 2018-2024 Total, S.A + * Copyright (c) 2018-2024 The Board of Trustees of the Leland Stanford Junior University + * Copyright (c) 2023-2024 Chevron + * Copyright (c) 2019- GEOS/GEOSX Contributors + * All rights reserved + * + * See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details. + * ------------------------------------------------------------------------------------------------------------ + */ + +#include "mainInterface/initialization.hpp" +#include "mainInterface/GeosxState.hpp" +#include "constitutive/fluid/twophasefluid/TwoPhaseFluid.hpp" +#include "physicsSolvers/PhysicsSolverManager.hpp" +#include "physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp" +#include "unitTests/fluidFlowTests/testCompFlowUtils.hpp" + +using namespace geos; +using namespace geos::dataRepository; +using namespace geos::constitutive; +using namespace geos::testing; + +CommandLineOptions g_commandLineOptions; + +// Sphinx start after input XML +char const *xmlInput = + R"xml( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + )xml"; +// Sphinx end before input XML + +template< typename LAMBDA > +void fillCellCenteredNumericalJacobian( ImmiscibleMultiphaseFlow & solver, + DomainPartition & domain, + real64 const perturbParameter, + arrayView1d< real64 > residual, + arrayView1d< real64 > residualOrig, + CRSMatrixView< real64, globalIndex > jacobian, + CRSMatrixView< real64, globalIndex > jacobianFD, + LAMBDA assembleFunction ) +{ + DofManager const & dofManager = solver.getDofManager(); + string const elemDofKey = dofManager.getKey( ImmiscibleMultiphaseFlow::viewKeyStruct::elemDofFieldString()); + + solver.forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, + MeshLevel & mesh, + arrayView1d< string const > const & regionNames ) + { + mesh.getElemManager().forElementSubRegions( regionNames, + [&]( localIndex const, + ElementSubRegionBase & subRegion ) + { + arrayView1d< integer const > const & elemGhostRank = subRegion.ghostRank(); + arrayView1d< globalIndex const > const & elemDofNumber = + subRegion.getReference< array1d< globalIndex > >( elemDofKey ); + + arrayView1d< real64 > const pres = + subRegion.getField< fields::flow::pressure >(); + + arrayView2d< real64, immiscibleFlow::USD_PHASE > const phaseVolumeFraction = + subRegion.getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); + + + for( localIndex ei = 0; ei < subRegion.size(); ++ei ) + { + if( elemGhostRank[ei] >= 0 ) + { + continue; + } + + // Step 1: compute numerical derivatives wrt pressure + solver.resetStateToBeginningOfStep( domain ); + pres.move( hostMemorySpace, true ); + + real64 const dP = perturbParameter * (pres[ei] + perturbParameter); + pres[ei] += dP; + +#if defined(GEOS_USE_CUDA) + pres.move( parallelDeviceMemorySpace, false ); +#endif + solver.updateState( domain ); + + residual.zero(); + jacobian.zero(); + assembleFunction( jacobian.toViewConstSizes(), residual.toView()); + + fillNumericalJacobian( residual.toViewConst(), + residualOrig.toViewConst(), + elemDofNumber[ei], + dP, + jacobianFD.toViewConstSizes()); + + + // Step 2: compute numerical derivatives wrt saturation + solver.resetStateToBeginningOfStep( domain ); + phaseVolumeFraction.move( hostMemorySpace, true ); + + real64 const dS = perturbParameter * (phaseVolumeFraction[ei][0] + perturbParameter); + phaseVolumeFraction[ei][0] += dS; + phaseVolumeFraction[ei][1] = 1- phaseVolumeFraction[ei][0]; + +#if defined(GEOS_USE_CUDA) + phaseVolumeFraction.move( parallelDeviceMemorySpace, false ); +#endif + + solver.updateState( domain ); + + residual.zero(); + jacobian.zero(); + assembleFunction( jacobian.toViewConstSizes(), residual.toView()); + + fillNumericalJacobian( residual.toViewConst(), + residualOrig.toViewConst(), + elemDofNumber[ei]+1, + dS, + jacobianFD.toViewConstSizes()); + } + } ); + } ); +} + +template< typename LAMBDA > +void testNumericalJacobian( ImmiscibleMultiphaseFlow & solver, + DomainPartition & domain, + real64 const perturbParameter, + real64 const relTol, + LAMBDA assembleFunction ) +{ + CRSMatrix< real64, globalIndex > const & jacobian = solver.getLocalMatrix(); + array1d< real64 > residual( jacobian.numRows()); + + // assemble the analytical residual + solver.resetStateToBeginningOfStep( domain ); + + residual.zero(); + jacobian.zero(); + + assembleFunction( jacobian.toViewConstSizes(), residual.toView()); + residual.move( hostMemorySpace, false ); + + // copy the analytical residual + array1d< real64 > residualOrig( residual ); + + // create the numerical jacobian + jacobian.move( hostMemorySpace ); + CRSMatrix< real64, globalIndex > jacobianFD( jacobian ); + jacobianFD.zero(); + + // fill jacobian FD + fillCellCenteredNumericalJacobian( solver, + domain, + perturbParameter, + residual.toView(), + residualOrig.toView(), + jacobian.toView(), + jacobianFD.toView(), + assembleFunction ); + + // assemble the analytical jacobian + solver.resetStateToBeginningOfStep( domain ); + + residual.zero(); + jacobian.zero(); + assembleFunction( jacobian.toViewConstSizes(), residual.toView()); + compareLocalMatrices( jacobian.toViewConst(), jacobianFD.toViewConst(), relTol ); +} + +class ImmiscibleMultiphaseFlowTest : public ::testing::Test +{ +public: + ImmiscibleMultiphaseFlowTest(): state( std::make_unique< CommandLineOptions >( g_commandLineOptions )) + {} + +protected: + void SetUp() override + { + setupProblemFromXML( state.getProblemManager(), xmlInput ); + solver = &state.getProblemManager().getPhysicsSolverManager().getGroup< ImmiscibleMultiphaseFlow >( "FlowSolver" ); + + DomainPartition & domain = state.getProblemManager().getDomainPartition(); + + solver->setupSystem( domain, + solver->getDofManager(), + solver->getLocalMatrix(), + solver->getSystemRhs(), + solver->getSystemSolution()); + + solver->implicitStepSetup( time, dt, domain ); + } + + static real64 constexpr time = 0.0; + static real64 constexpr dt = 1e4; + static real64 constexpr eps = std::numeric_limits< real64 >::epsilon(); + + GeosxState state; + ImmiscibleMultiphaseFlow *solver; +}; + +real64 constexpr ImmiscibleMultiphaseFlowTest::time; +real64 constexpr ImmiscibleMultiphaseFlowTest::dt; +real64 constexpr ImmiscibleMultiphaseFlowTest::eps; + + +TEST_F( ImmiscibleMultiphaseFlowTest, jacobianNumericalCheck_flux ) +{ + real64 const perturb = 0.000001; + real64 const tol = 1e-2; // 1% error margin + + DomainPartition & domain = state.getProblemManager().getDomainPartition(); + + testNumericalJacobian( *solver, domain, perturb, tol, + [&]( CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) + { + solver->assembleFluxTerms( dt, domain, solver->getDofManager(), localMatrix, localRhs ); + } ); +} + + +TEST_F( ImmiscibleMultiphaseFlowTest, jacobianNumericalCheck_accumulationVolumeBalance ) +{ + real64 const perturb = sqrt( eps ); + real64 const tol = 1e-2; // 1% error margin + + DomainPartition & domain = state.getProblemManager().getDomainPartition(); + + testNumericalJacobian( *solver, domain, perturb, tol, + [&] ( CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) + { + solver->assembleAccumulationTerm( domain, solver->getDofManager(), localMatrix, localRhs ); + } ); +} + + +int main( int argc, char * *argv ) +{ + ::testing::InitGoogleTest( &argc, argv ); + g_commandLineOptions = *geos::basicSetup( argc, argv ); + int const result = RUN_ALL_TESTS(); + geos::basicCleanup(); + return result; +} From fc01af3acdd315f1021f4e28b40b5444a63a8a2b Mon Sep 17 00:00:00 2001 From: Ammara-14 Date: Thu, 24 Oct 2024 10:56:13 -0700 Subject: [PATCH 047/102] added applySourceFlux --- .../fluidFlow/ImmiscibleMultiphaseFlow.cpp | 158 ++++++++++++++++++ .../fluidFlow/ImmiscibleMultiphaseFlow.hpp | 7 + 2 files changed, 165 insertions(+) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp index e941b4a376b..72a147e432e 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp @@ -942,6 +942,164 @@ void ImmiscibleMultiphaseFlow::applyDirichletBC( real64 const time_n, } ); } +void ImmiscibleMultiphaseFlow::applySourceFluxBC( real64 const time_n, + real64 const dt, + DomainPartition & domain, + DofManager const & dofManager, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) const +{ + GEOS_MARK_FUNCTION; + + FieldSpecificationManager & fsManager = FieldSpecificationManager::getInstance(); + + string const dofKey = dofManager.getKey( viewKeyStruct::elemDofFieldString() ); + + // Step 1: count individual source flux boundary conditions + + std::map< string, localIndex > bcNameToBcId; + localIndex bcCounter = 0; + + fsManager.forSubGroups< SourceFluxBoundaryCondition >( [&] ( SourceFluxBoundaryCondition const & bc ) + { + // collect all the bc names to idx + bcNameToBcId[bc.getName()] = bcCounter; + bcCounter++; + } ); + + if( bcCounter == 0 ) + { + return; + } + + // Step 2: count the set size for each source flux (each source flux may have multiple target sets) + + array1d< globalIndex > bcAllSetsSize( bcNameToBcId.size() ); + + computeSourceFluxSizeScalingFactor( time_n, + dt, + domain, + bcNameToBcId, + bcAllSetsSize.toView() ); + + // Step 3: we are ready to impose the boundary condition, normalized by the set size + + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, + MeshLevel & mesh, + arrayView1d< string const > const & ) + { + integer const isThermal = 0; + + fsManager.apply< ElementSubRegionBase, + SourceFluxBoundaryCondition >( time_n + dt, + mesh, + SourceFluxBoundaryCondition::catalogName(), + [&, isThermal]( SourceFluxBoundaryCondition const & fs, + string const & setName, + SortedArrayView< localIndex const > const & targetSet, + ElementSubRegionBase & subRegion, + string const & ) + { + if( targetSet.size() == 0 ) + { + return; + } + if( !subRegion.hasWrapper( dofKey ) ) + { + if( fs.getLogLevel() >= 1 ) + { + GEOS_LOG_RANK( GEOS_FMT( "{}: trying to apply SourceFlux, but its targetSet named '{}' intersects with non-simulated region named '{}'.", + getDataContext(), setName, subRegion.getName() ) ); + } + return; + } + + arrayView1d< globalIndex const > const dofNumber = subRegion.getReference< array1d< globalIndex > >( dofKey ); + arrayView1d< integer const > const ghostRank = subRegion.ghostRank(); + + // Step 3.1: get the values of the source boundary condition that need to be added to the rhs + + array1d< globalIndex > dofArray( targetSet.size() ); + array1d< real64 > rhsContributionArray( targetSet.size() ); + arrayView1d< real64 > rhsContributionArrayView = rhsContributionArray.toView(); + localIndex const rankOffset = dofManager.rankOffset(); + + RAJA::ReduceSum< parallelDeviceReduce, real64 > massProd( 0.0 ); + + // note that the dofArray will not be used after this step (simpler to use dofNumber instead) + fs.computeRhsContribution< FieldSpecificationAdd, + parallelDevicePolicy<> >( targetSet.toViewConst(), + time_n + dt, + dt, + subRegion, + dofNumber, + rankOffset, + localMatrix, + dofArray.toView(), + rhsContributionArrayView, + [] GEOS_HOST_DEVICE ( localIndex const ) + { + return 0.0; + } ); + + // Step 3.2: we are ready to add the right-hand side contributions, taking into account our equation layout + + // get the normalizer + real64 const sizeScalingFactor = bcAllSetsSize[bcNameToBcId.at( fs.getName())]; + integer const fluidPhaseId = fs.getComponent(); + integer const numFluidPhases = m_numPhases; + integer const useTotalMassEquation = 0; + forAll< parallelDevicePolicy<> >( targetSet.size(), [sizeScalingFactor, + targetSet, + rankOffset, + ghostRank, + fluidPhaseId, + numFluidPhases, + useTotalMassEquation, + dofNumber, + rhsContributionArrayView, + localRhs, + massProd] GEOS_HOST_DEVICE ( localIndex const a ) + { + // we need to filter out ghosts here, because targetSet may contain them + localIndex const ei = targetSet[a]; + if( ghostRank[ei] >= 0 ) + { + return; + } + + real64 const rhsValue = rhsContributionArrayView[a] / sizeScalingFactor; // scale the contribution by the sizeScalingFactor here! + massProd += rhsValue; + if( useTotalMassEquation > 0 ) + { + // for all "fluid components", we add the value to the total mass balance equation + globalIndex const totalMassBalanceRow = dofNumber[ei] - rankOffset; + localRhs[totalMassBalanceRow] += rhsValue; + if( fluidPhaseId < numFluidPhases - 1 ) + { + globalIndex const compMassBalanceRow = totalMassBalanceRow + fluidPhaseId + 1; // component mass bal equations are shifted + localRhs[compMassBalanceRow] += rhsValue; + } + } + else + { + globalIndex const compMassBalanceRow = dofNumber[ei] - rankOffset + fluidPhaseId; + localRhs[compMassBalanceRow] += rhsValue; + } + } ); + + // SourceFluxStatsAggregator::forAllFluxStatWrappers( subRegion, fs.getName(), + // [&]( SourceFluxStatsAggregator::WrappedStats & wrapper ) + // { + // // set the new sub-region statistics for this timestep + // array1d< real64 > massProdArr{ m_numPhases }; + // massProdArr[fluidPhaseId] = massProd.get(); + // wrapper.gatherTimeStepStats( time, dt, massProdArr.toViewConst(), targetSet.size() ); + // } ); + } ); + } ); +} + real64 ImmiscibleMultiphaseFlow::calculateResidualNorm( real64 const & GEOS_UNUSED_PARAM( time_n ), real64 const & GEOS_UNUSED_PARAM( dt ), diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp index 8abacdc7145..2a13371b122 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp @@ -192,6 +192,13 @@ class ImmiscibleMultiphaseFlow : public FlowSolverBase CRSMatrixView< real64, globalIndex const > const & localMatrix, arrayView1d< real64 > const & localRhs ) const; +void + applySourceFluxBC( real64 const time_n, + real64 const dt, + DomainPartition & domain, + DofManager const & dofManager, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) const; /** * @brief function to set the next time step size * @param[in] currentDt the current time step size From da993f628a7158e396fd73ff3da612926b0090f2 Mon Sep 17 00:00:00 2001 From: Ammara-14 Date: Thu, 24 Oct 2024 12:30:24 -0700 Subject: [PATCH 048/102] minor fix on applySourceFluxBC --- .../fluidFlow/ImmiscibleMultiphaseFlow.cpp | 32 ++++++++++++------- .../fluidFlow/ImmiscibleMultiphaseFlow.hpp | 13 ++++---- 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp index 72a147e432e..bcc7c82f8ce 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp @@ -759,6 +759,9 @@ void ImmiscibleMultiphaseFlow::applyBoundaryConditions( real64 const time_n, // apply pressure boundary conditions. applyDirichletBC( time_n, dt, dofManager, domain, localMatrix.toViewConstSizes(), localRhs.toView() ); +// apply flux boundary conditions + applySourceFluxBC( time_n, dt, dofManager, domain, localMatrix.toViewConstSizes(), localRhs.toView() ); + // for( localIndex row = 0; row < localMatrix.toViewConstSizes().numRows(); ++row ) // { // std::cout << "row " << row << std::endl; @@ -942,12 +945,12 @@ void ImmiscibleMultiphaseFlow::applyDirichletBC( real64 const time_n, } ); } -void ImmiscibleMultiphaseFlow::applySourceFluxBC( real64 const time_n, - real64 const dt, - DomainPartition & domain, - DofManager const & dofManager, - CRSMatrixView< real64, globalIndex const > const & localMatrix, - arrayView1d< real64 > const & localRhs ) const +void ImmiscibleMultiphaseFlow::applySourceFluxBC( real64 const time, + real64 const dt, + DofManager const & dofManager, + DomainPartition & domain, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) const { GEOS_MARK_FUNCTION; @@ -976,7 +979,7 @@ void ImmiscibleMultiphaseFlow::applySourceFluxBC( real64 const time_n, array1d< globalIndex > bcAllSetsSize( bcNameToBcId.size() ); - computeSourceFluxSizeScalingFactor( time_n, + computeSourceFluxSizeScalingFactor( time, dt, domain, bcNameToBcId, @@ -988,18 +991,25 @@ void ImmiscibleMultiphaseFlow::applySourceFluxBC( real64 const time_n, MeshLevel & mesh, arrayView1d< string const > const & ) { - integer const isThermal = 0; fsManager.apply< ElementSubRegionBase, - SourceFluxBoundaryCondition >( time_n + dt, + SourceFluxBoundaryCondition >( time + dt, mesh, SourceFluxBoundaryCondition::catalogName(), - [&, isThermal]( SourceFluxBoundaryCondition const & fs, + [&]( SourceFluxBoundaryCondition const & fs, string const & setName, SortedArrayView< localIndex const > const & targetSet, ElementSubRegionBase & subRegion, string const & ) { + if( fs.getLogLevel() >= 1 && m_nonlinearSolverParameters.m_numNewtonIterations == 0 ) + { + globalIndex const numTargetElems = MpiWrapper::sum< globalIndex >( targetSet.size() ); + GEOS_LOG_RANK_0( GEOS_FMT( bcLogMessage, + getName(), time+dt, fs.getCatalogName(), fs.getName(), + setName, subRegion.getName(), fs.getScale(), numTargetElems ) ); + } + if( targetSet.size() == 0 ) { return; @@ -1029,7 +1039,7 @@ void ImmiscibleMultiphaseFlow::applySourceFluxBC( real64 const time_n, // note that the dofArray will not be used after this step (simpler to use dofNumber instead) fs.computeRhsContribution< FieldSpecificationAdd, parallelDevicePolicy<> >( targetSet.toViewConst(), - time_n + dt, + time + dt, dt, subRegion, dofNumber, diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp index 2a13371b122..565a2b1a562 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp @@ -192,13 +192,12 @@ class ImmiscibleMultiphaseFlow : public FlowSolverBase CRSMatrixView< real64, globalIndex const > const & localMatrix, arrayView1d< real64 > const & localRhs ) const; -void - applySourceFluxBC( real64 const time_n, - real64 const dt, - DomainPartition & domain, - DofManager const & dofManager, - CRSMatrixView< real64, globalIndex const > const & localMatrix, - arrayView1d< real64 > const & localRhs ) const; + void applySourceFluxBC( real64 const time, + real64 const dt, + DofManager const & dofManager, + DomainPartition & domain, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) const; /** * @brief function to set the next time step size * @param[in] currentDt the current time step size From 9f0c7c5d2bc1d219f4a3d89a2d37e2ab6337dc8f Mon Sep 17 00:00:00 2001 From: rpiazza87 Date: Thu, 24 Oct 2024 14:51:32 -0700 Subject: [PATCH 049/102] included iterative solvers --- .../linearAlgebra/CMakeLists.txt | 1 + .../interfaces/hypre/HypreMGR.cpp | 6 ++ .../mgrStrategies/ImmiscibleMultiphaseFVM.hpp | 97 +++++++++++++++++++ .../testLinearSolverParametersEnums.cpp | 1 + .../utilities/LinearSolverParameters.hpp | 2 + .../fluidFlow/ImmiscibleMultiphaseFlow.cpp | 2 + 6 files changed, 109 insertions(+) create mode 100644 src/coreComponents/linearAlgebra/interfaces/hypre/mgrStrategies/ImmiscibleMultiphaseFVM.hpp diff --git a/src/coreComponents/linearAlgebra/CMakeLists.txt b/src/coreComponents/linearAlgebra/CMakeLists.txt index 095544ff4aa..d9b72819f54 100644 --- a/src/coreComponents/linearAlgebra/CMakeLists.txt +++ b/src/coreComponents/linearAlgebra/CMakeLists.txt @@ -101,6 +101,7 @@ if( ENABLE_HYPRE ) interfaces/hypre/mgrStrategies/CompositionalMultiphaseReservoirHybridFVM.hpp interfaces/hypre/mgrStrategies/HybridSinglePhasePoromechanics.hpp interfaces/hypre/mgrStrategies/Hydrofracture.hpp + interfaces/hypre/mgrStrategies/ImmiscibleMultiphaseFVM.hpp interfaces/hypre/mgrStrategies/LagrangianContactMechanics.hpp interfaces/hypre/mgrStrategies/MultiphasePoromechanics.hpp interfaces/hypre/mgrStrategies/SinglePhasePoromechanicsEmbeddedFractures.hpp diff --git a/src/coreComponents/linearAlgebra/interfaces/hypre/HypreMGR.cpp b/src/coreComponents/linearAlgebra/interfaces/hypre/HypreMGR.cpp index a14f0ac6b5b..f92e208ac5e 100644 --- a/src/coreComponents/linearAlgebra/interfaces/hypre/HypreMGR.cpp +++ b/src/coreComponents/linearAlgebra/interfaces/hypre/HypreMGR.cpp @@ -26,6 +26,7 @@ #include "linearAlgebra/interfaces/hypre/mgrStrategies/CompositionalMultiphaseReservoirHybridFVM.hpp" #include "linearAlgebra/interfaces/hypre/mgrStrategies/HybridSinglePhasePoromechanics.hpp" #include "linearAlgebra/interfaces/hypre/mgrStrategies/Hydrofracture.hpp" +#include "linearAlgebra/interfaces/hypre/mgrStrategies/ImmiscibleMultiphaseFVM.hpp" #include "linearAlgebra/interfaces/hypre/mgrStrategies/LagrangianContactMechanics.hpp" #include "linearAlgebra/interfaces/hypre/mgrStrategies/MultiphasePoromechanics.hpp" #include "linearAlgebra/interfaces/hypre/mgrStrategies/MultiphasePoromechanicsReservoirFVM.hpp" @@ -187,6 +188,11 @@ void hypre::mgr::createMGR( LinearSolverParameters const & params, setStrategy< SolidMechanicsEmbeddedFractures >( params.mgr, numComponentsPerField, precond, mgrData ); break; } + case LinearSolverParameters::MGR::StrategyType::immiscibleMultiphaseFVM: + { + setStrategy< ImmiscibleMultiphaseFVM >( params.mgr, numComponentsPerField, precond, mgrData ); + break; + } default: { GEOS_ERROR( "Unsupported MGR strategy: " << params.mgr.strategy ); diff --git a/src/coreComponents/linearAlgebra/interfaces/hypre/mgrStrategies/ImmiscibleMultiphaseFVM.hpp b/src/coreComponents/linearAlgebra/interfaces/hypre/mgrStrategies/ImmiscibleMultiphaseFVM.hpp new file mode 100644 index 00000000000..1fe5b33f15d --- /dev/null +++ b/src/coreComponents/linearAlgebra/interfaces/hypre/mgrStrategies/ImmiscibleMultiphaseFVM.hpp @@ -0,0 +1,97 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * SPDX-License-Identifier: LGPL-2.1-only + * + * Copyright (c) 2016-2024 Lawrence Livermore National Security LLC + * Copyright (c) 2018-2024 Total, S.A + * Copyright (c) 2018-2024 The Board of Trustees of the Leland Stanford Junior University + * Copyright (c) 2023-2024 Chevron + * Copyright (c) 2019- GEOS/GEOSX Contributors + * All rights reserved + * + * See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details. + * ------------------------------------------------------------------------------------------------------------ + */ + +/** + * @file ImmiscibleMultiphaseFVM.hpp + */ + +#ifndef GEOS_LINEARALGEBRA_INTERFACES_HYPREMGRIMMISCIBLEMULTIPHASEFVM_HPP_ +#define GEOS_LINEARALGEBRA_INTERFACES_HYPREMGRIMMISCIBLEMULTIPHASEFVM_HPP_ + +#include "linearAlgebra/interfaces/hypre/HypreMGR.hpp" + +namespace geos +{ + +namespace hypre +{ + +namespace mgr +{ + +/** + * @brief ImmiscibleMultiphaseFVM strategy. + * + * Labels description stored in point_marker_array + * 0 = pressure + * 1 = phase volume fraction + * ... = phase volume fractions + * numLabels - 1 = phase volume fraction + * + * 1-level MGR reduction strategy: + * - 1st level: eliminate the reservoir phase volume fractions + * - The coarse grid (pressure system) is solved with BoomerAMG. + * + */ +class ImmiscibleMultiphaseFVM : public MGRStrategyBase< 1 > +{ +public: + /** + * @brief Constructor. + * @param numComponentsPerField array with number of components for each field + */ + explicit ImmiscibleMultiphaseFVM( arrayView1d< int const > const & numComponentsPerField ) + : MGRStrategyBase( LvArray::integerConversion< HYPRE_Int >( numComponentsPerField[0] ) ) + { + // Level 0: eliminate last density which corresponds to the volume constraint equation + // m_labels[0].resize( m_numBlocks - 1 ); + // std::iota( m_labels[0].begin(), m_labels[0].end(), 0 ); + + // Level 0: eliminate the phase volume fractions + m_labels[0].push_back( 0 ); + + setupLabels(); + + m_levelFRelaxType[0] = MGRFRelaxationType::none; + m_levelInterpType[0] = MGRInterpolationType::injection; + m_levelRestrictType[0] = MGRRestrictionType::blockColLumped; // True-IMPES + m_levelCoarseGridMethod[0] = MGRCoarseGridMethod::galerkin; + m_levelGlobalSmootherType[0] = MGRGlobalSmootherType::ilu0; + m_levelGlobalSmootherIters[0] = 1; + } + + /** + * @brief Setup the MGR strategy. + * @param precond preconditioner wrapper + * @param mgrData auxiliary MGR data + */ + void setup( LinearSolverParameters::MGR const &, + HyprePrecWrapper & precond, + HypreMGRData & mgrData ) + { + setReduction( precond, mgrData ); + + // Configure the BoomerAMG solver used as mgr coarse solver for the pressure reduced system + setPressureAMG( mgrData.coarseSolver ); + } +}; + +} // namespace mgr + +} // namespace hypre + +} // namespace geos + +#endif /*GEOS_LINEARALGEBRA_INTERFACES_HYPREMGRCOMPOSITIONALMULTIPHASEFVM_HPP_*/ diff --git a/src/coreComponents/linearAlgebra/unitTests/testLinearSolverParametersEnums.cpp b/src/coreComponents/linearAlgebra/unitTests/testLinearSolverParametersEnums.cpp index 5194fab06bd..928adc90b45 100644 --- a/src/coreComponents/linearAlgebra/unitTests/testLinearSolverParametersEnums.cpp +++ b/src/coreComponents/linearAlgebra/unitTests/testLinearSolverParametersEnums.cpp @@ -97,6 +97,7 @@ TEST( LinearSolverParametersEnums, MGRStrategyType ) ASSERT_EQ( "compositionalMultiphaseHybridFVM", toString( EnumType::compositionalMultiphaseHybridFVM ) ); ASSERT_EQ( "compositionalMultiphaseReservoirFVM", toString( EnumType::compositionalMultiphaseReservoirFVM ) ); ASSERT_EQ( "compositionalMultiphaseReservoirHybridFVM", toString( EnumType::compositionalMultiphaseReservoirHybridFVM ) ); + ASSERT_EQ( "immiscibleMultiphaseFVM", toString( EnumType::immiscibleMultiphaseFVM ) ); ASSERT_EQ( "multiphasePoromechanics", toString( EnumType::multiphasePoromechanics ) ); ASSERT_EQ( "hydrofracture", toString( EnumType::hydrofracture ) ); ASSERT_EQ( "lagrangianContactMechanics", toString( EnumType::lagrangianContactMechanics ) ); diff --git a/src/coreComponents/linearAlgebra/utilities/LinearSolverParameters.hpp b/src/coreComponents/linearAlgebra/utilities/LinearSolverParameters.hpp index 51c2239c0a6..bf060c88d8d 100644 --- a/src/coreComponents/linearAlgebra/utilities/LinearSolverParameters.hpp +++ b/src/coreComponents/linearAlgebra/utilities/LinearSolverParameters.hpp @@ -282,6 +282,7 @@ struct LinearSolverParameters compositionalMultiphaseHybridFVM, ///< hybrid finite volume compositional multiphase flow compositionalMultiphaseReservoirFVM, ///< finite volume compositional multiphase flow with wells compositionalMultiphaseReservoirHybridFVM, ///< hybrid finite volume compositional multiphase flow with wells + immiscibleMultiphaseFVM, ///< finite volume immiscible multiphase flow reactiveCompositionalMultiphaseOBL, ///< finite volume reactive compositional flow with OBL thermalCompositionalMultiphaseFVM, ///< finite volume thermal compositional multiphase flow multiphasePoromechanics, ///< multiphase poromechanics with finite volume compositional multiphase flow @@ -374,6 +375,7 @@ ENUM_STRINGS( LinearSolverParameters::MGR::StrategyType, "compositionalMultiphaseHybridFVM", "compositionalMultiphaseReservoirFVM", "compositionalMultiphaseReservoirHybridFVM", + "immiscibleMultiphaseFVM", "reactiveCompositionalMultiphaseOBL", "thermalCompositionalMultiphaseFVM", "multiphasePoromechanics", diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp index bcc7c82f8ce..38942e62c64 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp @@ -184,6 +184,8 @@ void ImmiscibleMultiphaseFlow::setConstitutiveNames( ElementSubRegionBase & subR void ImmiscibleMultiphaseFlow::initializePreSubGroups() { + m_linearSolverParameters.get().mgr.strategy = LinearSolverParameters::MGR::StrategyType::immiscibleMultiphaseFVM; + FlowSolverBase::initializePreSubGroups(); DomainPartition & domain = this->getGroupByPath< DomainPartition >( "/Problem/domain" ); From 645748d28d6f94fc8f18eda8db479d30f814147f Mon Sep 17 00:00:00 2001 From: DENEL Bertrand Date: Fri, 25 Oct 2024 11:10:27 -0500 Subject: [PATCH 050/102] Fooled compiler to prevent an unusedlambdacapture error --- .../physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp index 38942e62c64..e0150d21b06 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp @@ -1060,7 +1060,7 @@ void ImmiscibleMultiphaseFlow::applySourceFluxBC( real64 const time, real64 const sizeScalingFactor = bcAllSetsSize[bcNameToBcId.at( fs.getName())]; integer const fluidPhaseId = fs.getComponent(); integer const numFluidPhases = m_numPhases; - integer const useTotalMassEquation = 0; + integer useTotalMassEquation = 0; forAll< parallelDevicePolicy<> >( targetSet.size(), [sizeScalingFactor, targetSet, rankOffset, From 6c8eefaedefff4c5f3a21ec9016a65a477c8c6bc Mon Sep 17 00:00:00 2001 From: DENEL Bertrand Date: Mon, 28 Oct 2024 12:17:30 -0500 Subject: [PATCH 051/102] Added input files for BuckleyLeverett, CapillaryPressure and Gravity tests. --- .../buckleyLeverett_base.xml | 181 ++++++++++++++++ .../buckleyLeverett_benchmark.xml | 62 ++++++ .../immiscibleTwoPhase_CapillaryPressure.xml | 190 +++++++++++++++++ .../initialSaturation1.txt | 10 + .../initialSaturation2.txt | 11 + .../x.txt | 10 + .../y.txt | 1 + .../z.txt | 1 + .../immiscibleTwoPhase_Gravity.xml | 195 ++++++++++++++++++ .../initialPressure.txt | 10 + .../initialSaturation1.txt | 10 + .../initialSaturation2.txt | 10 + .../immiscibleTwoPhase_Gravity/x.txt | 1 + .../immiscibleTwoPhase_Gravity/y.txt | 1 + .../immiscibleTwoPhase_Gravity/z.txt | 10 + 15 files changed, 703 insertions(+) create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_BuckleyLeverett/buckleyLeverett_base.xml create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_BuckleyLeverett/buckleyLeverett_benchmark.xml create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_CapillaryPressure/immiscibleTwoPhase_CapillaryPressure.xml create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_CapillaryPressure/initialSaturation1.txt create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_CapillaryPressure/initialSaturation2.txt create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_CapillaryPressure/x.txt create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_CapillaryPressure/y.txt create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_CapillaryPressure/z.txt create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_Gravity/immiscibleTwoPhase_Gravity.xml create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_Gravity/initialPressure.txt create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_Gravity/initialSaturation1.txt create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_Gravity/initialSaturation2.txt create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_Gravity/x.txt create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_Gravity/y.txt create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_Gravity/z.txt diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_BuckleyLeverett/buckleyLeverett_base.xml b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_BuckleyLeverett/buckleyLeverett_base.xml new file mode 100644 index 00000000000..4bd8a93c7c8 --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_BuckleyLeverett/buckleyLeverett_base.xml @@ -0,0 +1,181 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_BuckleyLeverett/buckleyLeverett_benchmark.xml b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_BuckleyLeverett/buckleyLeverett_benchmark.xml new file mode 100644 index 00000000000..df684689511 --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_BuckleyLeverett/buckleyLeverett_benchmark.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_CapillaryPressure/immiscibleTwoPhase_CapillaryPressure.xml b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_CapillaryPressure/immiscibleTwoPhase_CapillaryPressure.xml new file mode 100644 index 00000000000..46d250ee052 --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_CapillaryPressure/immiscibleTwoPhase_CapillaryPressure.xml @@ -0,0 +1,190 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_CapillaryPressure/initialSaturation1.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_CapillaryPressure/initialSaturation1.txt new file mode 100644 index 00000000000..1c03b9c1871 --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_CapillaryPressure/initialSaturation1.txt @@ -0,0 +1,10 @@ +1 +1 +1 +1 +1 +0 +0 +0 +0 +0 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_CapillaryPressure/initialSaturation2.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_CapillaryPressure/initialSaturation2.txt new file mode 100644 index 00000000000..cd9d2981d61 --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_CapillaryPressure/initialSaturation2.txt @@ -0,0 +1,11 @@ +0 +0 +0 +0 +0 +1 +1 +1 +1 +1 + diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_CapillaryPressure/x.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_CapillaryPressure/x.txt new file mode 100644 index 00000000000..f43a1f14d26 --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_CapillaryPressure/x.txt @@ -0,0 +1,10 @@ +0.5 +1.5 +2.5 +3.5 +4.5 +5.5 +6.5 +7.5 +8.5 +9.5 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_CapillaryPressure/y.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_CapillaryPressure/y.txt new file mode 100644 index 00000000000..2eb3c4fe4ee --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_CapillaryPressure/y.txt @@ -0,0 +1 @@ +0.5 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_CapillaryPressure/z.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_CapillaryPressure/z.txt new file mode 100644 index 00000000000..2eb3c4fe4ee --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_CapillaryPressure/z.txt @@ -0,0 +1 @@ +0.5 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_Gravity/immiscibleTwoPhase_Gravity.xml b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_Gravity/immiscibleTwoPhase_Gravity.xml new file mode 100644 index 00000000000..b4390686079 --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_Gravity/immiscibleTwoPhase_Gravity.xml @@ -0,0 +1,195 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_Gravity/initialPressure.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_Gravity/initialPressure.txt new file mode 100644 index 00000000000..85a30e13876 --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_Gravity/initialPressure.txt @@ -0,0 +1,10 @@ +495.0 +485.0 +475.0 +465.0 +455.0 +400.0 +300.0 +200.0 +100.0 +0.0 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_Gravity/initialSaturation1.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_Gravity/initialSaturation1.txt new file mode 100644 index 00000000000..99f11f6b2e7 --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_Gravity/initialSaturation1.txt @@ -0,0 +1,10 @@ +0 +0 +0 +0 +0 +1 +1 +1 +1 +1 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_Gravity/initialSaturation2.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_Gravity/initialSaturation2.txt new file mode 100644 index 00000000000..1c03b9c1871 --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_Gravity/initialSaturation2.txt @@ -0,0 +1,10 @@ +1 +1 +1 +1 +1 +0 +0 +0 +0 +0 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_Gravity/x.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_Gravity/x.txt new file mode 100644 index 00000000000..2eb3c4fe4ee --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_Gravity/x.txt @@ -0,0 +1 @@ +0.5 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_Gravity/y.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_Gravity/y.txt new file mode 100644 index 00000000000..2eb3c4fe4ee --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_Gravity/y.txt @@ -0,0 +1 @@ +0.5 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_Gravity/z.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_Gravity/z.txt new file mode 100644 index 00000000000..f43a1f14d26 --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_Gravity/z.txt @@ -0,0 +1,10 @@ +0.5 +1.5 +2.5 +3.5 +4.5 +5.5 +6.5 +7.5 +8.5 +9.5 From 05f0287c0bb89845912d662012156a1b001cfa1f Mon Sep 17 00:00:00 2001 From: DENEL Bertrand Date: Mon, 28 Oct 2024 12:39:36 -0500 Subject: [PATCH 052/102] Fixed xml format. --- .../buckleyLeverett_benchmark.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_BuckleyLeverett/buckleyLeverett_benchmark.xml b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_BuckleyLeverett/buckleyLeverett_benchmark.xml index df684689511..0fb90cd71d2 100644 --- a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_BuckleyLeverett/buckleyLeverett_benchmark.xml +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_BuckleyLeverett/buckleyLeverett_benchmark.xml @@ -1,4 +1,3 @@ - From 83086d067cda149f6643560c3f82424012fdd437 Mon Sep 17 00:00:00 2001 From: DENEL Bertrand Date: Mon, 28 Oct 2024 12:57:16 -0500 Subject: [PATCH 053/102] Updated unit test for better coverage. --- .../fluidFlow/ImmiscibleMultiphaseFlow.cpp | 22 +++++----- .../testImmiscibleMultiphaseFlow.cpp | 41 +++++++++++++++---- 2 files changed, 43 insertions(+), 20 deletions(-) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp index e0150d21b06..f5dfe772a65 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp @@ -185,7 +185,7 @@ void ImmiscibleMultiphaseFlow::setConstitutiveNames( ElementSubRegionBase & subR void ImmiscibleMultiphaseFlow::initializePreSubGroups() { m_linearSolverParameters.get().mgr.strategy = LinearSolverParameters::MGR::StrategyType::immiscibleMultiphaseFVM; - + FlowSolverBase::initializePreSubGroups(); DomainPartition & domain = this->getGroupByPath< DomainPartition >( "/Problem/domain" ); @@ -763,7 +763,7 @@ void ImmiscibleMultiphaseFlow::applyBoundaryConditions( real64 const time_n, // apply flux boundary conditions applySourceFluxBC( time_n, dt, dofManager, domain, localMatrix.toViewConstSizes(), localRhs.toView() ); - + // for( localIndex row = 0; row < localMatrix.toViewConstSizes().numRows(); ++row ) // { // std::cout << "row " << row << std::endl; @@ -948,11 +948,11 @@ void ImmiscibleMultiphaseFlow::applyDirichletBC( real64 const time_n, } void ImmiscibleMultiphaseFlow::applySourceFluxBC( real64 const time, - real64 const dt, - DofManager const & dofManager, - DomainPartition & domain, - CRSMatrixView< real64, globalIndex const > const & localMatrix, - arrayView1d< real64 > const & localRhs ) const + real64 const dt, + DofManager const & dofManager, + DomainPartition & domain, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) const { GEOS_MARK_FUNCTION; @@ -999,10 +999,10 @@ void ImmiscibleMultiphaseFlow::applySourceFluxBC( real64 const time, mesh, SourceFluxBoundaryCondition::catalogName(), [&]( SourceFluxBoundaryCondition const & fs, - string const & setName, - SortedArrayView< localIndex const > const & targetSet, - ElementSubRegionBase & subRegion, - string const & ) + string const & setName, + SortedArrayView< localIndex const > const & targetSet, + ElementSubRegionBase & subRegion, + string const & ) { if( fs.getLogLevel() >= 1 && m_nonlinearSolverParameters.m_numNewtonIterations == 0 ) { diff --git a/src/coreComponents/unitTests/fluidFlowTests/testImmiscibleMultiphaseFlow.cpp b/src/coreComponents/unitTests/fluidFlowTests/testImmiscibleMultiphaseFlow.cpp index 9e2c4cc4b06..a1fc731b321 100644 --- a/src/coreComponents/unitTests/fluidFlowTests/testImmiscibleMultiphaseFlow.cpp +++ b/src/coreComponents/unitTests/fluidFlowTests/testImmiscibleMultiphaseFlow.cpp @@ -88,7 +88,7 @@ char const *xmlInput = + materialList="{ fluid, rock, relperm, capPressure }"/> @@ -113,7 +113,7 @@ char const *xmlInput = - + permeabilityModelName="rockPerm" /> + name="nullSolid" /> + compressibility="0.0" /> - + phaseRelPermMaxValue="{ 1.0, 1.0 }" /> + + @@ -406,7 +413,7 @@ real64 constexpr ImmiscibleMultiphaseFlowTest::dt; real64 constexpr ImmiscibleMultiphaseFlowTest::eps; -TEST_F( ImmiscibleMultiphaseFlowTest, jacobianNumericalCheck_flux ) +TEST_F( ImmiscibleMultiphaseFlowTest, jacobianNumericalCheck_fluxTerm ) { real64 const perturb = 0.000001; real64 const tol = 1e-2; // 1% error margin @@ -422,7 +429,7 @@ TEST_F( ImmiscibleMultiphaseFlowTest, jacobianNumericalCheck_flux ) } -TEST_F( ImmiscibleMultiphaseFlowTest, jacobianNumericalCheck_accumulationVolumeBalance ) +TEST_F( ImmiscibleMultiphaseFlowTest, jacobianNumericalCheck_accumulationTerm ) { real64 const perturb = sqrt( eps ); real64 const tol = 1e-2; // 1% error margin @@ -438,6 +445,22 @@ TEST_F( ImmiscibleMultiphaseFlowTest, jacobianNumericalCheck_accumulationVolumeB } +TEST_F( ImmiscibleMultiphaseFlowTest, jacobianNumericalCheck_full ) +{ + real64 const perturb = 0.000001; + real64 const tol = 1e-2; // 1% error margin + + DomainPartition & domain = state.getProblemManager().getDomainPartition(); + + testNumericalJacobian( *solver, domain, perturb, tol, + [&] ( CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) + { + solver->assembleSystem( time, dt, domain, solver->getDofManager(), localMatrix, localRhs ); + } ); +} + + int main( int argc, char * *argv ) { ::testing::InitGoogleTest( &argc, argv ); From a99d949d5d1f7896ca3ecdc01390d35f36d08af5 Mon Sep 17 00:00:00 2001 From: DENEL Bertrand Date: Tue, 29 Oct 2024 16:06:31 -0500 Subject: [PATCH 054/102] Added SPE10_layer84 test case. --- ...iscibleTwoPhase_GravitySegregation_1d.xml} | 0 .../initialPressure.txt | 0 .../initialSaturation1.txt | 0 .../initialSaturation2.txt | 0 .../x.txt | 0 .../y.txt | 0 .../z.txt | 0 .../dens_pvdo.txt | 3 + ...ibleTwoPhase_SPE10_layer84_base_direct.xml | 238 + ...eTwoPhase_SPE10_layer84_base_iterative.xml | 238 + ...woPhase_SPE10_layer84_benchmark_direct.xml | 54 + ...hase_SPE10_layer84_benchmark_iterative.xml | 54 + .../layer84_permx.geos | 13200 ++++++++++++++++ .../layer84_permy.geos | 13200 ++++++++++++++++ .../layer84_permz.geos | 13200 ++++++++++++++++ .../layer84_poro.geos | 13200 ++++++++++++++++ .../pres_pvdo.txt | 3 + .../visc_pvdo.txt | 3 + .../xlin.geos | 60 + .../ylin.geos | 220 + .../zlin.geos | 1 + .../mgrStrategies/ImmiscibleMultiphaseFVM.hpp | 2 +- 22 files changed, 53675 insertions(+), 1 deletion(-) rename inputFiles/immiscibleMultiphaseFlow/{immiscibleTwoPhase_Gravity/immiscibleTwoPhase_Gravity.xml => immiscibleTwoPhase_GravitySegregation_1d/immiscibleTwoPhase_GravitySegregation_1d.xml} (100%) rename inputFiles/immiscibleMultiphaseFlow/{immiscibleTwoPhase_Gravity => immiscibleTwoPhase_GravitySegregation_1d}/initialPressure.txt (100%) rename inputFiles/immiscibleMultiphaseFlow/{immiscibleTwoPhase_Gravity => immiscibleTwoPhase_GravitySegregation_1d}/initialSaturation1.txt (100%) rename inputFiles/immiscibleMultiphaseFlow/{immiscibleTwoPhase_Gravity => immiscibleTwoPhase_GravitySegregation_1d}/initialSaturation2.txt (100%) rename inputFiles/immiscibleMultiphaseFlow/{immiscibleTwoPhase_Gravity => immiscibleTwoPhase_GravitySegregation_1d}/x.txt (100%) rename inputFiles/immiscibleMultiphaseFlow/{immiscibleTwoPhase_Gravity => immiscibleTwoPhase_GravitySegregation_1d}/y.txt (100%) rename inputFiles/immiscibleMultiphaseFlow/{immiscibleTwoPhase_Gravity => immiscibleTwoPhase_GravitySegregation_1d}/z.txt (100%) create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/dens_pvdo.txt create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/immiscibleTwoPhase_SPE10_layer84_base_direct.xml create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/immiscibleTwoPhase_SPE10_layer84_base_iterative.xml create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/immiscibleTwoPhase_SPE10_layer84_benchmark_direct.xml create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/immiscibleTwoPhase_SPE10_layer84_benchmark_iterative.xml create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/layer84_permx.geos create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/layer84_permy.geos create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/layer84_permz.geos create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/layer84_poro.geos create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/pres_pvdo.txt create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/visc_pvdo.txt create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/xlin.geos create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/ylin.geos create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/zlin.geos diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_Gravity/immiscibleTwoPhase_Gravity.xml b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_GravitySegregation_1d/immiscibleTwoPhase_GravitySegregation_1d.xml similarity index 100% rename from inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_Gravity/immiscibleTwoPhase_Gravity.xml rename to inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_GravitySegregation_1d/immiscibleTwoPhase_GravitySegregation_1d.xml diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_Gravity/initialPressure.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_GravitySegregation_1d/initialPressure.txt similarity index 100% rename from inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_Gravity/initialPressure.txt rename to inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_GravitySegregation_1d/initialPressure.txt diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_Gravity/initialSaturation1.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_GravitySegregation_1d/initialSaturation1.txt similarity index 100% rename from inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_Gravity/initialSaturation1.txt rename to inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_GravitySegregation_1d/initialSaturation1.txt diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_Gravity/initialSaturation2.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_GravitySegregation_1d/initialSaturation2.txt similarity index 100% rename from inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_Gravity/initialSaturation2.txt rename to inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_GravitySegregation_1d/initialSaturation2.txt diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_Gravity/x.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_GravitySegregation_1d/x.txt similarity index 100% rename from inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_Gravity/x.txt rename to inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_GravitySegregation_1d/x.txt diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_Gravity/y.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_GravitySegregation_1d/y.txt similarity index 100% rename from inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_Gravity/y.txt rename to inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_GravitySegregation_1d/y.txt diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_Gravity/z.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_GravitySegregation_1d/z.txt similarity index 100% rename from inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_Gravity/z.txt rename to inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_GravitySegregation_1d/z.txt diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/dens_pvdo.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/dens_pvdo.txt new file mode 100644 index 00000000000..363a10269a5 --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/dens_pvdo.txt @@ -0,0 +1,3 @@ +761.90476190476190476190 +784.31372549019607843137 +792.07920792079207920792 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/immiscibleTwoPhase_SPE10_layer84_base_direct.xml b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/immiscibleTwoPhase_SPE10_layer84_base_direct.xml new file mode 100644 index 00000000000..54064522013 --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/immiscibleTwoPhase_SPE10_layer84_base_direct.xml @@ -0,0 +1,238 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/immiscibleTwoPhase_SPE10_layer84_base_iterative.xml b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/immiscibleTwoPhase_SPE10_layer84_base_iterative.xml new file mode 100644 index 00000000000..13264fe80d0 --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/immiscibleTwoPhase_SPE10_layer84_base_iterative.xml @@ -0,0 +1,238 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/immiscibleTwoPhase_SPE10_layer84_benchmark_direct.xml b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/immiscibleTwoPhase_SPE10_layer84_benchmark_direct.xml new file mode 100644 index 00000000000..35ab5d391b3 --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/immiscibleTwoPhase_SPE10_layer84_benchmark_direct.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/immiscibleTwoPhase_SPE10_layer84_benchmark_iterative.xml b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/immiscibleTwoPhase_SPE10_layer84_benchmark_iterative.xml new file mode 100644 index 00000000000..d20765c07bb --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/immiscibleTwoPhase_SPE10_layer84_benchmark_iterative.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/layer84_permx.geos b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/layer84_permx.geos new file mode 100644 index 00000000000..d83867f1511 --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/layer84_permx.geos @@ -0,0 +1,13200 @@ +0.064542 +0.034083 +0.033865 +12.584 +25.506 +49.557 +110.05 +3.1658 +1864.7 +554.89 +778.92 +166.98 +1152.9 +430.23 +940.06 +345.37 +229.37 +390.37 +744.79 +110.79 +189.92 +61.175 +45.341 +299.3 +268.93 +51.619 +25.666 +116.14 +0.10857 +0.30584 +0.11793 +0.097815 +0.18215 +0.13971 +0.091116 +0.046364 +0.10297 +0.079578 +0.013536 +0.03645 +0.10576 +0.45575 +0.19143 +0.081675 +521.47 +588.83 +425.18 +60.599 +71.636 +285.38 +361.31 +17.056 +47.555 +148.49 +65.429 +34.797 +111.85 +136.38 +98.327 +169.98 +0.11286 +0.10634 +0.081667 +0.052393 +32.541 +36.477 +166.46 +2237.7 +678.13 +492.44 +793.61 +285.87 +1633.4 +676.45 +371.46 +426.83 +379.78 +369.9 +288.81 +69.299 +67.002 +25.327 +39.998 +379.97 +257.87 +65.124 +28.595 +98.913 +0.28881 +0.33028 +0.25872 +0.1233 +0.048856 +0.22513 +0.37565 +0.026637 +0.059152 +0.034875 +0.01443 +0.019086 +0.11767 +0.099196 +0.07389 +0.034775 +432.54 +324 +52.078 +142.62 +195.34 +231.22 +246.73 +317.3 +61.988 +65.189 +258.83 +34.475 +138.53 +276.58 +166.55 +293.29 +0.065883 +0.097745 +0.20938 +0.79875 +0.49302 +0.23443 +44.765 +200.05 +608.83 +190.16 +566.79 +230.07 +998.9 +648.59 +145.2 +617.66 +574.48 +340.95 +139.57 +73.181 +85.964 +22.285 +47.058 +120.34 +235.96 +27.214 +24.529 +70.772 +0.63261 +0.18382 +0.19455 +0.12733 +0.086306 +0.15792 +0.23827 +0.38131 +0.15722 +0.24469 +0.043473 +0.12284 +0.25926 +0.087617 +0.036858 +0.055697 +246.6 +376.72 +87.035 +252.94 +338.94 +141.44 +308.2 +237.84 +47.03 +90.055 +141.26 +38.305 +423.1 +231.6 +144.91 +193.52 +0.19582 +0.029963 +0.16623 +0.18874 +0.63653 +0.13589 +0.46928 +0.069859 +84.093 +297.66 +709.97 +332.23 +1179.3 +960.02 +99.835 +679.55 +690.79 +230.29 +64.782 +74.962 +63.969 +29.326 +31.055 +62.858 +78.211 +49.509 +27.538 +52.3 +0.14683 +0.073425 +0.079791 +0.23118 +0.15686 +0.37766 +0.23192 +0.18254 +0.13246 +0.36985 +0.28115 +0.45961 +0.2039 +0.14442 +0.12089 +0.035193 +51.816 +279.09 +98.52 +165.48 +205.67 +84.122 +126.41 +144.61 +141.12 +84.454 +98.735 +29.543 +30.702 +32.005 +64.901 +190.82 +0.24328 +0.045128 +0.27136 +0.17964 +0.28686 +0.31372 +0.10344 +0.027707 +65.548 +192.02 +1056.6 +451.14 +568.55 +884.24 +143.95 +218.63 +354.26 +223.68 +182.13 +73.648 +12.494 +23.241 +24.469 +120.55 +87.03 +59.859 +63.365 +57.563 +205.47 +0.10258 +0.036084 +0.22701 +0.34276 +0.15466 +0.037823 +0.042638 +0.41338 +0.31336 +1.0557 +0.074098 +0.12464 +0.063393 +0.15806 +0.071952 +0.1078 +161.37 +108.25 +289.25 +122.91 +205.05 +483.29 +86.51 +38.502 +49.36 +34.694 +21.44 +222.37 +340.5 +35.465 +382.73 +0.17405 +0.24344 +0.21956 +0.11204 +0.50225 +0.40387 +0.13347 +44.621 +49.595 +205.14 +110.97 +231.59 +598.07 +241.89 +127.55 +257.68 +301.45 +264.14 +205.78 +945.86 +406.89 +33.532 +88.773 +139.35 +43.266 +31.504 +50.983 +70.095 +116.72 +0.012884 +0.021406 +0.11139 +0.13991 +0.23014 +0.083808 +0.14631 +0.4154 +0.39946 +0.58834 +0.10903 +0.023152 +0.062313 +0.44326 +0.042737 +0.11187 +0.20606 +833.41 +200.2 +185.46 +139.76 +433.92 +115.96 +43.992 +58.488 +38.38 +15.999 +142.26 +272.44 +125.73 +374.02 +0.36356 +0.23023 +0.34597 +0.57646 +0.69528 +0.18271 +12.786 +22.28 +72.075 +293.26 +69.144 +144.89 +185.07 +65.641 +227.53 +69.682 +112.23 +163.93 +110.52 +557.42 +414.41 +44.922 +90.015 +218.6 +32.666 +31.722 +28.023 +82.649 +82.841 +0.2781 +0.15826 +0.2424 +0.26436 +0.079702 +0.068927 +0.1803 +0.22496 +0.30583 +0.92788 +0.13457 +0.011549 +0.072593 +0.26906 +0.1108 +1005.4 +403.63 +357.54 +179.15 +227.94 +169.22 +248.56 +256.55 +135.76 +46.386 +87.288 +80.658 +268.25 +110.56 +70.52 +354.73 +0.17062 +0.19122 +1.4683 +0.28591 +1.1344 +0.61433 +14.97 +31.062 +70.954 +232.54 +179.12 +120.54 +133.6 +89.496 +52.812 +379.81 +200.82 +100.85 +75.243 +157.67 +347.75 +206.1 +229.32 +114.01 +20.654 +33.827 +40.613 +76.305 +22.376 +63.505 +0.11355 +0.14114 +0.011373 +0.057265 +0.20586 +0.21325 +0.055662 +0.093884 +0.14534 +0.048081 +0.041314 +0.046246 +0.03562 +760.16 +1217 +745.93 +795.84 +99.913 +204.06 +123.77 +253.1 +204.19 +152.04 +138.02 +84.878 +82.619 +104.82 +76.898 +59.541 +152.44 +0.29373 +0.13717 +0.29431 +4.3611 +0.32076 +0.83081 +27.533 +64.722 +31.243 +177.8 +211.94 +158.24 +69.265 +56.738 +307.65 +339.36 +257.26 +60.568 +76.742 +169.22 +444.62 +208.19 +372.92 +89.071 +34.606 +36.319 +27.375 +106.42 +24.527 +75.613 +2362.9 +0.072295 +0.033354 +0.018601 +0.089319 +0.086002 +0.066354 +0.17864 +0.32434 +0.066334 +0.061923 +0.1465 +0.20517 +459.33 +444.1 +699.99 +768.6 +99.921 +170.93 +233.83 +1389.3 +377.83 +235.73 +251.35 +104.14 +64.791 +76.809 +0.16251 +0.24275 +0.030701 +0.45119 +0.20232 +0.5466 +0.65022 +0.55413 +0.10716 +46.39 +83.23 +37.374 +213.88 +51.885 +22.977 +74.532 +168.72 +187.73 +234.98 +232.28 +30.974 +294.42 +566.89 +529.52 +245.32 +313.32 +257.05 +385.16 +157.47 +129.16 +135.72 +27.896 +78.059 +3242.2 +975.66 +0.072112 +0.029737 +0.06779 +0.035362 +0.083346 +0.22955 +0.071457 +0.12459 +0.11444 +3172.4 +278.98 +589.88 +584.53 +403.27 +750.9 +217.59 +194.54 +164.41 +467.93 +1360.8 +290.77 +253.07 +355.59 +196.4 +326.85 +0.14956 +0.11366 +0.15315 +0.37969 +0.23949 +0.10672 +0.079027 +0.080941 +0.064121 +72.658 +43.561 +50.816 +137.24 +25.553 +16.117 +53.033 +347.26 +201.64 +299.23 +176.54 +33.877 +462.13 +136.41 +112.91 +138.66 +221.94 +188.74 +803.49 +116.76 +912.63 +127.61 +125.75 +166.11 +101.56 +911.79 +186.47 +0.08453 +0.039313 +0.049767 +0.40395 +0.10691 +0.016847 +161.96 +577.41 +2099.7 +241.99 +319.12 +2261.6 +2442.1 +209.19 +146.51 +159.46 +348.49 +263.67 +462.89 +129.9 +107.08 +133.09 +711.3 +275.4 +0.055833 +0.14019 +0.06268 +0.20509 +0.2143 +0.25294 +0.52994 +0.079145 +0.090655 +47.828 +26.751 +31.94 +55.881 +172.71 +31.025 +83.53 +472.45 +473.52 +180.58 +68.023 +18.186 +513.8 +87.376 +62.507 +172.49 +268.2 +211.04 +371.53 +41.53 +79.049 +533.62 +218.18 +33.722 +149.07 +76.799 +505.42 +0.028038 +0.12757 +0.098478 +0.40759 +0.23775 +352.3 +361.97 +507.75 +1063 +463.21 +934.6 +1800.2 +2441.5 +161.96 +71.926 +129.75 +276.79 +752.58 +373.23 +55.897 +222.43 +267.63 +855 +547.59 +754.28 +0.12624 +0.056341 +0.091799 +0.18029 +0.54194 +0.17822 +0.24298 +0.22995 +115.58 +55.764 +51.966 +60.55 +83.883 +40.962 +111.47 +437.03 +625.37 +60.861 +110.38 +35.098 +344.29 +228.48 +232.04 +284.52 +453.57 +223.13 +454.08 +79.732 +78.156 +327.48 +269.76 +928.72 +373.5 +51.307 +107.01 +0.027685 +0.049666 +0.1022 +0.21973 +60.967 +291.13 +482.85 +889.98 +1986.5 +279.88 +2971.5 +1887.5 +1686.1 +177.06 +246 +239.78 +133.89 +475.95 +498.08 +73.064 +150.48 +197.38 +1038 +828.51 +0.054693 +0.027247 +0.042157 +0.034732 +0.01816 +0.1158 +0.22036 +0.023251 +0.041459 +224.57 +76.117 +70.432 +230.56 +57.266 +57.341 +263.94 +298.04 +535.68 +44.06 +238 +335.79 +115.85 +1013.3 +547.52 +490.85 +748.42 +196.51 +235.21 +38.992 +174.13 +614.47 +508.34 +1093.2 +207.76 +76.966 +2303.5 +6468.3 +3378 +3568.4 +232.79 +102.71 +154.52 +296.64 +666.62 +0.044901 +0.033646 +0.074568 +1040.8 +1456 +484.49 +372.73 +165.15 +117.14 +69.967 +328.01 +411.26 +271.49 +2909.1 +1338.5 +0.10492 +0.09618 +0.17501 +0.042574 +0.045451 +0.032037 +0.064184 +0.13178 +0.045783 +0.1872 +380.62 +112.71 +86.495 +250.1 +79.037 +90.322 +220.58 +328.97 +146.02 +33.509 +428.75 +129.38 +131.41 +141.74 +518.04 +652.16 +824.41 +224.94 +455.9 +903.34 +368.35 +741.47 +394.17 +825.35 +719.21 +126.73 +53.909 +1682.2 +3920.8 +5337.6 +7227.1 +63.056 +196.31 +207.31 +0.018731 +0.081244 +0.03119 +0.034039 +1053 +1256.4 +457.57 +714.14 +210.8 +436.48 +71.696 +183.29 +303.12 +691.12 +467.88 +0.043608 +0.057146 +0.34246 +0.13845 +0.050325 +0.10604 +0.022569 +0.10474 +0.17147 +0.26691 +0.66749 +375.88 +96.477 +186.03 +255.69 +93.254 +55.775 +109.36 +129.54 +117.51 +30.112 +702.12 +153.61 +217.21 +2400.3 +390.82 +528.63 +678.78 +169.76 +902.57 +786.16 +583.42 +1555.4 +273.07 +796.46 +692.55 +157.24 +64.409 +693.8 +1953.5 +4344.9 +4908.8 +6861.6 +115.13 +196.53 +0.010065 +0.005226 +0.015142 +0.044592 +841.66 +701.51 +569.97 +1404.1 +420 +945.03 +91.569 +372.7 +479.58 +867.86 +0.14671 +0.022754 +0.058072 +0.25578 +0.373 +0.12615 +0.10488 +0.040757 +0.038922 +0.1141 +1.5126 +5.2666 +0.50732 +1.732 +57.488 +162.49 +111.95 +109.48 +146.69 +203.31 +60.671 +24.116 +83.11 +271.01 +83.895 +1165.8 +506.66 +704.71 +537.11 +226.38 +486.78 +850.98 +792.5 +221.86 +97.752 +287.8 +506.4 +259.7 +63.291 +259.46 +281.67 +4594.3 +2977.5 +5929.5 +154.72 +0.18093 +0.023153 +0.013063 +0.062635 +1468.4 +93.999 +988.36 +1146.2 +1007.5 +631.03 +1563.5 +555.79 +373.58 +897.79 +510.13 +1.5394 +0.071805 +0.41543 +0.22775 +0.16103 +0.14905 +0.3836 +0.059474 +0.068608 +0.37691 +0.56713 +4.4797 +0.21818 +0.065353 +45.733 +83.197 +154.54 +98.953 +44.568 +100.51 +36.408 +38.667 +107.35 +26.764 +36.915 +691.38 +423.64 +503.46 +211.26 +398.14 +109.26 +933.74 +664.61 +245.23 +97.1 +911.37 +794.12 +234.75 +101.76 +94.315 +292.58 +825.85 +2257.3 +1809.7 +65.881 +1.2157 +0.20489 +0.041237 +0.055386 +0.22325 +252.36 +123.01 +3059.1 +383.73 +219.59 +460.94 +1039.4 +352.3 +127.91 +0.057797 +0.60867 +0.15544 +0.21043 +0.25787 +0.2688 +0.20647 +0.5459 +0.072486 +0.041144 +0.061576 +0.37612 +0.22198 +0.061339 +0.018407 +77.257 +137.34 +199.79 +93.143 +69.812 +97.414 +41.885 +30.648 +41.72 +51.445 +670.2 +421.82 +327.57 +761.36 +250.34 +271.42 +128.38 +230.9 +86.811 +177.7 +0.046207 +1417.1 +447.81 +359.22 +225.09 +85.249 +398.68 +1450.6 +1573.5 +3203.5 +2303.9 +0.085812 +0.12855 +0.058119 +0.058183 +82.827 +338.13 +24.439 +351.91 +600.56 +371.71 +288.02 +777.4 +126.96 +135.74 +748.38 +0.28827 +0.92401 +0.099892 +0.063414 +0.047237 +0.23694 +0.1953 +0.016815 +0.062956 +0.10603 +0.20299 +0.068023 +0.015586 +0.079782 +0.069472 +70.9 +168.8 +83.003 +66.23 +89.389 +39.068 +11.904 +33.453 +148.55 +689.3 +510.42 +255.16 +396.9 +233.01 +234.7 +148.23 +192.56 +132.09 +377.94 +20000 +641.09 +535.18 +422.13 +203.7 +103.14 +164.08 +384.23 +3595.2 +3326.6 +0.43644 +0.87682 +0.21329 +216.08 +67.867 +88.226 +332.5 +40.323 +75.919 +571.44 +681.47 +703.88 +751.92 +96.307 +55.034 +817.01 +857.88 +1.8641 +0.30399 +0.023181 +0.095362 +0.085263 +0.02839 +0.069068 +0.045199 +0.077594 +0.14852 +0.08044 +0.045626 +0.029042 +0.062378 +38.99 +97.05 +125.67 +129.75 +182.08 +45.691 +58.096 +471.37 +87.832 +407.89 +519.4 +270.96 +490.63 +379.78 +260.58 +235.88 +4558.9 +101.19 +220.15 +20000 +183.09 +491.78 +784.9 +192.65 +266.35 +321.63 +260.47 +3947.8 +0.15472 +0.1247 +0.086955 +0.15396 +17.211 +197.68 +92.417 +434.23 +30.135 +188.99 +381.47 +3151.1 +1147.3 +222.12 +171.38 +7.9534 +559.02 +608.7 +281.97 +0.22344 +0.082356 +0.052349 +0.04474 +0.006468 +0.085523 +0.055831 +0.16622 +0.071888 +0.051486 +0.010634 +0.10723 +94.868 +34.1 +112.63 +81.7 +125.74 +102.26 +30.577 +327.97 +341.43 +87.525 +262.53 +432.91 +77.231 +391.52 +312.13 +246.19 +3986.3 +3196.6 +391.99 +250 +217.76 +199.5 +1131.3 +322.69 +290.15 +257.5 +376.57 +0.32552 +0.20756 +0.41813 +0.46419 +0.42621 +10.378 +15.666 +43.303 +927.56 +735.71 +103.51 +149.84 +381.74 +2065.3 +108.7 +155.15 +74.238 +9.7458 +564.77 +739.74 +318.89 +254.18 +0.05016 +0.15938 +0.44953 +0.64601 +0.021304 +0.046599 +0.037551 +0.050755 +0.049153 +670.11 +313.38 +202.78 +25.986 +138.02 +74.498 +167.35 +896.58 +477.79 +617.6 +187.95 +76.598 +386.53 +705.47 +172.13 +444.19 +508.81 +1394.4 +2491.8 +140.81 +363.63 +1131.9 +402.83 +125.62 +989.79 +768.08 +217.83 +93.863 +0.073146 +0.1392 +0.066525 +0.064315 +0.086 +0.062137 +11.013 +11.121 +89.624 +505.35 +227.03 +59.997 +179.86 +623.13 +167.34 +145.28 +106.3 +183.74 +23.414 +353.03 +346.34 +118.33 +0.38988 +0.048508 +0.14228 +0.059671 +0.058192 +0.15036 +0.42229 +0.22523 +0.10655 +0.17156 +629.91 +505.61 +227.95 +55.159 +147.97 +85.203 +1598 +1243.7 +1036.3 +168.31 +141.9 +180.92 +582.24 +442.22 +261.19 +309.28 +5384.5 +0.29577 +148.73 +99.551 +213.17 +735.85 +767.04 +157.13 +49.371 +999.46 +467.36 +0.15842 +0.031487 +0.040931 +0.20878 +0.15259 +0.33171 +11.363 +8.2247 +6.9178 +208.51 +238.45 +246.52 +124.96 +57.279 +103.69 +133.34 +154.73 +198.42 +606.44 +49.994 +543.56 +310.61 +254.47 +0.094992 +0.086519 +0.12653 +0.068546 +0.09167 +0.047976 +0.080055 +0.18503 +0.065935 +436.44 +383.64 +177.41 +189.57 +89.964 +289.68 +975.21 +341 +109.23 +51.145 +165.32 +79.5 +220.37 +1144.4 +564.87 +6233.4 +326.03 +258.97 +80.484 +104.37 +70.665 +172.14 +607.39 +1315.4 +2035.7 +411.98 +953.81 +0.037991 +0.056282 +0.039962 +0.059559 +0.1805 +0.27062 +1.4387 +4.6608 +138.79 +113.75 +10.047 +15.914 +60.87 +56.757 +23.284 +144.9 +133.17 +242 +76.539 +366.93 +67.01 +439.08 +601.39 +292.76 +1679.2 +0.20646 +0.090226 +0.051762 +0.16651 +0.063797 +0.03858 +0.053665 +0.053837 +342.42 +357.26 +0.14388 +207.49 +364.89 +243.9 +677.55 +177.9 +172.02 +39.464 +144.03 +163.96 +106.44 +9344.4 +7339.1 +134.06 +283.62 +697.86 +107.66 +112.39 +175.22 +626.53 +0.13755 +992.8 +1401 +411.5 +847.72 +1832.8 +0.26055 +0.37582 +0.081309 +0.17563 +0.12407 +625.01 +1241.6 +80.451 +17.904 +18.647 +6.8496 +2.6433 +84.082 +46.953 +144.48 +145.76 +229.34 +112.21 +175.66 +133.41 +493.73 +777.01 +438.79 +2223.4 +0.24289 +0.090909 +0.054286 +0.035886 +0.042054 +0.017021 +0.036003 +0.033485 +0.056762 +714.37 +112.05 +302.28 +827.07 +292.39 +458.93 +363.44 +172.85 +108.84 +252.63 +234.15 +12024 +102.83 +134.89 +254.97 +507.3 +693.86 +234.78 +224.19 +0.21142 +0.15445 +0.069956 +494.82 +610.78 +622.52 +1029.1 +1772.1 +301.51 +0.18088 +0.12615 +0.083816 +332.2 +0.045379 +0.018357 +0.024315 +14.364 +14.716 +7.4866 +58.744 +77.545 +79.97 +223.5 +171.29 +236.06 +163.15 +255.84 +516.74 +0.011899 +717.16 +296.42 +2101.7 +733.89 +0.012212 +0.024235 +0.027301 +0.02557 +0.010744 +0.024276 +0.04748 +94.542 +80.874 +99.301 +307.32 +868.22 +682.78 +437.97 +482.38 +372.26 +307.69 +36.34 +155.75 +81.583 +127.78 +106.65 +101.24 +424.24 +433.57 +202.87 +0.13553 +0.020352 +0.054023 +0.037423 +0.023142 +372.85 +519 +526.58 +834.26 +298.72 +90.51 +597.77 +1087.5 +0.026311 +0.032221 +0.067858 +0.037855 +0.067948 +0.059987 +104.08 +95.129 +147.7 +143.52 +323.02 +148.59 +487.15 +596.4 +863.81 +937.84 +355.45 +198.74 +179.55 +2036.5 +0.017805 +0.027843 +0.037913 +0.039088 +0.02631 +0.022821 +235.55 +117.99 +43.88 +90.053 +129.31 +249.62 +1078.8 +1344 +496.9 +430.09 +374.78 +29.099 +94.298 +143.63 +162.17 +142.08 +71.208 +92.798 +222.48 +2987.3 +0.04223 +0.023116 +0.16845 +0.029541 +0.043063 +988.46 +276.95 +668.82 +306.4 +721.62 +381.79 +817.32 +2100 +7.8004 +0.029002 +0.063596 +0.032126 +164.94 +166.56 +162.23 +144.35 +91.474 +103.39 +87.628 +244.26 +319.17 +553.78 +654.83 +461.8 +511.82 +208.13 +340.31 +392 +786.86 +0.036235 +0.080712 +0.089838 +0.16975 +0.051504 +227.24 +147.28 +82.719 +23.627 +46.817 +132.27 +188.31 +860.68 +575.89 +288.7 +763.1 +73.746 +116.37 +96.039 +164.91 +73.634 +144.24 +70.428 +70.998 +3815.2 +2041.4 +0.13388 +0.13954 +0.13916 +0.023716 +0.019203 +921.26 +287.58 +790.68 +1085 +998.12 +371.65 +545.76 +1367.7 +11.845 +0.011215 +5747.8 +10258 +841.05 +117.53 +153.13 +169.41 +120.66 +144.86 +285.1 +289.18 +130.82 +217.66 +205.8 +288.47 +432.23 +181.83 +251.83 +1077.2 +736.78 +0.32814 +0.064353 +0.18512 +0.041463 +120.27 +190.09 +106.56 +93.094 +25.747 +79.519 +192.22 +230.07 +1161.7 +550.42 +341.85 +177.41 +134.28 +177.31 +105.5 +164.13 +120.76 +59.415 +40.681 +45.245 +2568.5 +3029.3 +4473 +8542.1 +0.022298 +0.035673 +0.035346 +977.49 +394.62 +913.86 +646.09 +2371.4 +297.66 +279.83 +977.18 +124.68 +0.031991 +4585.1 +9669.5 +970.54 +171.93 +84.455 +211.19 +1630 +2793 +465.26 +144.91 +148.96 +147.98 +133.03 +416.29 +324.25 +118.46 +236.1 +1085.5 +790.89 +0.3891 +0.13582 +0.083521 +0.044139 +100.48 +89.16 +120.24 +87.716 +73.05 +68.88 +144.98 +387.36 +938.04 +528.41 +1160 +458.76 +175.31 +148.55 +59.324 +170.47 +178.92 +48.419 +70.68 +4090.7 +5340.3 +3119.6 +6201.5 +8242.8 +16749 +12469 +102.8 +660.59 +217.71 +879.71 +649.42 +2004.5 +212.34 +288.94 +225.95 +308.23 +562.39 +5784.4 +5212.6 +351 +125.83 +75.04 +476.05 +0.054004 +619.38 +227.82 +191.05 +71.829 +204.96 +161.22 +178.01 +193.32 +163.02 +433.27 +1454.6 +754.13 +271.06 +0.019848 +0.11036 +0.047296 +106.88 +95.278 +95.915 +111.79 +50.32 +153.07 +200.04 +365.17 +1101.2 +729.67 +1837.1 +0.02878 +195.7 +202.86 +72.614 +212.57 +189.85 +51.696 +176.23 +150.16 +6093.7 +3746.3 +4104.9 +18194 +33.859 +83.221 +62.64 +272.86 +306.46 +910.8 +624.76 +1693.9 +175.95 +291.47 +156.22 +514.46 +696.38 +345.06 +4924.7 +730.5 +211.28 +210.53 +895.53 +0.10021 +18.802 +183.56 +236.6 +65.828 +161.85 +79.685 +318.64 +453.92 +841.64 +805.6 +1730.2 +751.39 +190.02 +0.048484 +0.050683 +0.038711 +244.93 +180.15 +90.256 +106.18 +51.704 +591.79 +180.03 +479.85 +496.25 +1132.1 +1525 +46.547 +156.02 +224.87 +129.04 +391.41 +260.57 +53.318 +82.291 +19.442 +66.122 +4506.7 +271.49 +105.16 +60.001 +155.7 +91.994 +244.82 +966.31 +514.52 +338.86 +1287.5 +104.38 +271.78 +281.53 +894.33 +757.46 +334.09 +5967 +1082.9 +256.95 +157.1 +1930.3 +0.16706 +0.23357 +20.546 +135.89 +57.231 +71.034 +63.959 +268.83 +538.06 +364.27 +1327.3 +577.67 +453.41 +471.46 +0.032577 +0.096693 +0.030402 +0.094 +0.074792 +78.624 +65.998 +39.28 +306.65 +344.83 +510.79 +772.37 +694.05 +0.03337 +69.284 +270.64 +290.06 +142.75 +261.81 +144.63 +35.737 +83.141 +27.761 +1207.6 +538.28 +198.34 +222.84 +161.79 +336.02 +119.24 +226.28 +747.55 +1313.5 +339.85 +831.74 +102.72 +0.18271 +0.088591 +369.18 +764.11 +302.49 +30.472 +2402.1 +432.65 +316.17 +2418.3 +0.35435 +33.611 +32.474 +98.578 +117.95 +91.226 +102.23 +233.26 +279.37 +279.32 +280.64 +370.97 +731.11 +595.38 +889.63 +0.36594 +0.019786 +0.10423 +0.040005 +32.878 +117.14 +73.209 +232.31 +252.47 +651 +183.84 +0.10801 +27.506 +188.62 +509.14 +266.7 +168.45 +172.56 +109.56 +55.617 +252.76 +607.03 +865.22 +472.78 +268.46 +632.95 +328.74 +331.95 +83.728 +261.86 +661.03 +1607.8 +329.39 +0.39644 +0.43631 +0.39884 +0.37352 +44.636 +260.62 +246.54 +541.03 +128.29 +3362.3 +602.47 +2247.1 +2084.1 +19.81 +32.902 +110.82 +289.74 +271.99 +370.5 +156.57 +148.43 +271.8 +246.04 +308.34 +513.93 +437.25 +722.29 +0.055349 +0.064215 +0.060211 +35.199 +43.349 +82.321 +116.22 +259.09 +300.14 +914.46 +0.051738 +0.04402 +845.58 +114.58 +867.06 +171.51 +100.07 +45.13 +49.633 +600.8 +400.96 +1189.2 +438.15 +333.41 +334.24 +506.34 +1009.4 +329.67 +193.95 +650.63 +20000 +9786.2 +14168 +0.38846 +0.26615 +0.15357 +0.16432 +0.22051 +284.96 +503.52 +226.77 +172.01 +21.474 +285.29 +2905.1 +2362.1 +1942.4 +83.699 +73.349 +222.87 +209.62 +370.26 +269.28 +1046.7 +189.19 +151.17 +400.13 +284.85 +1056.1 +353.95 +0.055006 +0.037158 +0.058991 +53.239 +74.838 +61.747 +135.69 +136.02 +768.77 +653.57 +1313.4 +1847.1 +958.28 +44.354 +273.64 +80.772 +66.911 +66.443 +15.835 +310.34 +831.23 +874.79 +260.78 +201.9 +514.62 +357.33 +921.11 +20000 +20000 +20000 +20000 +333.48 +401.43 +404.68 +255.02 +0.080324 +0.13234 +0.13573 +0.068013 +140.55 +115.24 +186.85 +25.299 +20.742 +4288.7 +2670.6 +1431.7 +2539.6 +1994.2 +163.74 +126.74 +399.95 +995.58 +896.65 +446.85 +108.79 +239.23 +284.56 +511.5 +543.92 +0.45725 +0.092232 +230.78 +142.68 +65.559 +185.2 +158.98 +306.39 +1413.1 +0.07376 +0.090521 +0.16032 +1730.2 +37.544 +178.01 +141.25 +115.97 +51.94 +15.798 +542.98 +640.16 +1060 +245.69 +0.32582 +0.32508 +0.15372 +20000 +13832 +16616 +20000 +20000 +17596 +1783.3 +563.1 +180.11 +696.35 +0.059353 +159.76 +75.456 +118.69 +258.25 +1071 +129.54 +100.61 +9.3211 +1943.4 +2179.4 +2620 +1787.8 +154.85 +104.89 +45.203 +277.6 +885.44 +383.8 +79.739 +94.45 +904.37 +651.6 +0.067856 +1.7106 +0.041091 +170.08 +53.609 +83.895 +228.6 +157 +445.71 +1656.3 +215.4 +214.53 +323.24 +263.59 +722.11 +1039.8 +128.05 +172.71 +35.944 +11.673 +384.68 +0.054976 +0.056484 +0.54125 +0.3867 +0.40171 +0.29226 +20000 +20000 +8921.1 +20000 +20000 +12660 +6466.7 +1395.4 +147.94 +356.31 +0.05831 +0.24296 +86.243 +153.72 +331.3 +674.56 +551.37 +132.56 +13.224 +9.2287 +1452 +1480.5 +1856.3 +2736.7 +924.97 +42.436 +61.555 +114.05 +89.524 +156.76 +59.733 +584.63 +384.05 +0.092109 +0.22831 +0.29556 +109.33 +107.95 +123.46 +112.61 +120.59 +422.5 +2442.1 +3099.1 +307.89 +538.93 +460.33 +408.81 +2071.4 +4612.8 +225.9 +28.076 +17.87 +11.689 +9.242 +0.25543 +0.26083 +0.18224 +0.56139 +15142 +20000 +20000 +10371 +20000 +20000 +49.477 +36.952 +1063.7 +202.47 +196.9 +0.21012 +0.097823 +64.417 +174.78 +533.15 +413.96 +11.479 +68.185 +43.638 +13.485 +10.291 +1656.3 +1165.1 +2048.9 +102.33 +68.549 +71.977 +238.51 +103.31 +101.99 +48.875 +43.378 +0.13187 +0.046404 +0.16419 +0.64175 +0.29613 +49.225 +195.35 +288.27 +177.93 +207.91 +1662.8 +2651.5 +219.76 +498.8 +594.19 +527.32 +2374.4 +3434.4 +262.9 +49.239 +15.312 +9.3444 +5.436 +0.076231 +0.017327 +0.36808 +20000 +13640 +20000 +20000 +9387.2 +20000 +64.693 +36.159 +23.757 +771.4 +0.081627 +0.033605 +0.031971 +89.904 +79.553 +127.75 +395.49 +11.296 +43.573 +91.118 +47.1 +77.163 +17.461 +63.621 +180.78 +2007.6 +181.5 +145.37 +35.083 +170.21 +95.539 +60.156 +41.245 +23.391 +69.86 +0.307 +0.077237 +0.53307 +0.58566 +0.23657 +77.484 +112.25 +930.2 +143.83 +1019.6 +2324.4 +362.98 +243.42 +419.78 +1374 +5187.8 +3194.1 +398.6 +47.299 +9.0425 +13.18 +4.9446 +0.11462 +0.07608 +0.11186 +20000 +20000 +20000 +13096 +4292.8 +20000 +20.069 +25.817 +46.058 +38.489 +0.047873 +0.038792 +0.20183 +0.60446 +0.067169 +0.18499 +0.084948 +12.808 +60.674 +79.399 +53.937 +20.307 +20.734 +92.872 +180.4 +980.75 +299.44 +113.78 +25.021 +41.784 +65.546 +64.539 +55.268 +32.824 +59.059 +75.303 +0.20485 +0.30454 +0.80804 +0.30306 +0.21426 +272.83 +488.85 +639.85 +1251 +1381.8 +756.77 +224.57 +542.77 +2310.6 +4436 +251.9 +57.621 +0.12822 +22.411 +4.2519 +6.105 +34.843 +6.9776 +0.60394 +20000 +19465 +17455 +4239.9 +4172.6 +16588 +65.404 +32.694 +65.236 +78.405 +0.036713 +0.19119 +0.31752 +0.56851 +0.039968 +0.029245 +30.799 +26.298 +227.98 +129.25 +61.616 +26.855 +33.661 +93.855 +116.68 +700.72 +213.94 +126.5 +25.579 +84.178 +49.549 +8.5375 +28.304 +26.286 +106.17 +45.605 +0.049351 +0.17173 +0.69811 +0.052192 +0.35938 +243.35 +315.11 +1604.8 +3327.6 +1522.5 +3306.4 +687.62 +412.38 +1979.8 +571.65 +891.01 +95.9 +779.36 +871.37 +3.5137 +9.9101 +32.84 +15.585 +25.363 +20000 +8196.4 +8226.6 +3601.3 +7732.2 +5508.6 +5874.1 +23.066 +51.827 +60.333 +154.1 +0.71506 +0.056885 +0.11326 +0.015941 +197.96 +62.482 +23.728 +213.73 +244.99 +26.328 +9.1281 +45.411 +120.23 +96.569 +907.68 +540.16 +68.777 +94.686 +65.724 +46.961 +12.289 +27.698 +29.001 +108.36 +49.029 +47.646 +0.27776 +0.82964 +0.06854 +99.124 +77.718 +140.85 +1004.8 +7960.1 +2334.2 +4649.5 +1402.8 +1298.7 +1638.8 +0.072125 +688.5 +2079.8 +584.88 +3649 +4.3504 +10.351 +43.181 +21.816 +11.112 +19465 +9088.5 +8617.2 +3232.9 +3562.4 +2620.5 +2983.7 +0.10192 +0.050717 +0.11496 +30.927 +31.204 +77.521 +0.055553 +471.38 +179.76 +100.76 +47.416 +415.41 +29.07 +19.549 +12.258 +52.935 +81.248 +104 +1043.8 +314.65 +138.76 +253.09 +101.64 +56.527 +9.4114 +12.099 +86.919 +145.69 +84.334 +59.532 +3.5592 +1.4952 +0.20445 +126.68 +112.03 +119.11 +351.73 +1289.2 +1421.1 +1711.5 +2364.9 +2012.4 +2515.3 +1119.9 +0.028167 +1173.3 +1219.5 +3030.7 +6.4432 +24.535 +40.614 +20.341 +10.027 +33.453 +5069.9 +4820.1 +4278.2 +5420.9 +1473.5 +0.057922 +0.22536 +0.10497 +0.16221 +0.10651 +0.021999 +433.08 +700.8 +856.04 +361.87 +243.95 +115.59 +55.019 +29.417 +9.5029 +9.9344 +45.165 +166.51 +46.815 +879.39 +193.78 +128.07 +179.34 +108.69 +135.75 +5.5524 +20.318 +49.264 +85.334 +165.48 +63.665 +0.84262 +0.59375 +0.30898 +0.042635 +72.153 +204.03 +130.92 +637.33 +230.95 +2356.6 +1382.4 +1872.7 +1943.6 +20.261 +705.67 +873.58 +1404.3 +15.366 +2.9473 +60.206 +45.805 +26.319 +10.562 +19.043 +29.694 +2600.1 +2673.8 +0.081876 +0.043923 +0.2819 +0.11478 +0.028511 +0.084036 +2.7731 +134.4 +185.52 +112.87 +510.91 +520.47 +345.36 +0.063346 +73.226 +38.148 +9.8193 +11.886 +38.157 +1353.6 +1987.7 +272.93 +203.1 +116.25 +136.02 +105.43 +155.47 +5.4723 +18.547 +32.067 +182.26 +90.351 +109.49 +0.81705 +0.34805 +0.038671 +0.062894 +128.42 +215.59 +178.89 +915.24 +193.08 +886.74 +2050.6 +1852.2 +852.21 +163.03 +1351.8 +553.68 +32.529 +15.394 +7.4316 +33.642 +26.94 +47.707 +16.751 +21.442 +22.55 +1174.5 +2916.1 +0.055861 +0.021274 +0.035199 +0.12111 +0.030879 +0.065266 +7.5117 +74.467 +177.32 +281.32 +281.42 +577.49 +0.050091 +0.18737 +0.1568 +28.529 +27.63 +2517 +738.1 +933.11 +871.79 +320.2 +157.03 +134.77 +168.69 +435.01 +652.92 +1859.8 +925.77 +1486.1 +1661.3 +4411.9 +46.269 +0.20478 +0.39581 +0.14735 +0.025938 +0.007892 +169.87 +198.28 +784.71 +2717.8 +1377.4 +3238.6 +5057.7 +695.24 +195.7 +1475 +1.9986 +13.711 +16.673 +35.938 +15.221 +20.127 +65.248 +20.669 +39.491 +51.869 +1473.4 +0.024469 +0.049945 +0.47797 +0.054648 +0.032764 +0.081617 +0.012342 +10.976 +113.37 +468.65 +442.29 +271.33 +1267.8 +0.02819 +0.053603 +0.054862 +43.035 +350.07 +1881 +1500.1 +950.93 +515.64 +479.51 +1144 +1023 +592.2 +329.2 +947.42 +973.82 +1447.6 +2677.9 +4213.7 +1444.8 +11079 +0.030241 +0.069073 +0.036347 +0.03097 +0.058345 +0.066494 +175.42 +3026.1 +1156.2 +2183 +2936.2 +2181.8 +832.18 +153.02 +706.54 +3.2145 +9.2865 +11.159 +17.896 +17.044 +23.973 +85.297 +34.483 +88.593 +39.678 +0.21368 +0.032631 +0.050632 +1.04 +1.1297 +0.059103 +0.077958 +0.11299 +23.192 +35.882 +438.07 +225.29 +411.25 +791.82 +0.039732 +0.069966 +0.071924 +247.34 +634.64 +2155.8 +872.2 +861.18 +112.31 +98.951 +431.1 +1775.3 +1553 +694.85 +1883 +1581.8 +910.39 +2078.4 +2836.2 +3505.7 +553.37 +0.068438 +0.0474 +0.081545 +0.077128 +0.14198 +0.09065 +0.15977 +2837.4 +1414.8 +1445.8 +6372.8 +4334.1 +1119 +15.122 +11.556 +2.4852 +20.439 +21.996 +28.635 +27.434 +24.46 +138.18 +62.951 +85.102 +143.21 +0.058604 +0.022878 +0.019812 +0.19787 +0.48935 +0.030584 +0.022982 +0.050755 +21.166 +40.382 +159.58 +195.45 +539.41 +193.07 +32.902 +18.827 +73.82 +257.64 +336.34 +2065.9 +58.382 +27.374 +91.346 +178.89 +738.15 +832.97 +2162.5 +234.65 +2058.4 +762.53 +1245 +544.75 +647.57 +285.73 +423.48 +0.13564 +0.15352 +0.23669 +0.21923 +0.040201 +0.052 +0.15072 +51.245 +1021.1 +2010.3 +3525.3 +6405.1 +1013.6 +14.065 +10.346 +3.1605 +15.167 +13.149 +25.728 +22.907 +35.685 +147.94 +23.242 +6649.4 +0.090554 +0.011954 +0.023624 +0.071026 +0.049531 +0.045962 +0.11707 +0.044904 +0.003453 +22.756 +77.47 +204.08 +127.37 +401.03 +291.2 +0.45181 +13.075 +151.26 +97.186 +47.583 +124.12 +75.046 +41.142 +91.46 +182.45 +976.96 +672.16 +687.45 +446.96 +717.36 +517.9 +938.71 +636.23 +1017.9 +515.14 +28.852 +0.21398 +0.24414 +0.17823 +0.55816 +0.085047 +0.31459 +0.09849 +0.079809 +54.552 +3577.8 +2515.6 +1908.1 +1342.8 +8.5413 +5.534 +4.4049 +11.797 +17.816 +20.836 +49.496 +43.551 +101.72 +35.164 +20.077 +0.16516 +0.017769 +0.080451 +0.094329 +0.030378 +0.063156 +0.013578 +0.022231 +0.013782 +0.015439 +127.72 +177.31 +158.85 +541.11 +667.76 +21.918 +117.12 +94.865 +93.768 +28.75 +94.018 +187.67 +111.14 +267.7 +364.4 +1178.8 +1002 +356.12 +982.39 +224.03 +983.79 +154.17 +186.08 +286.98 +88.52 +49.485 +0.17155 +0.021736 +0.29292 +0.12531 +0.42716 +0.91892 +0.20216 +0.38024 +0.52909 +410.89 +1841.5 +1972.3 +27.504 +14.306 +4.465 +11.739 +23.305 +23.479 +17.397 +139.09 +68.664 +82.785 +20.509 +20000 +0.02774 +0.013818 +0.071988 +0.039631 +0.054121 +0.059862 +0.020456 +0.021124 +0.059129 +0.09583 +99.545 +206.83 +121.91 +60.056 +20.178 +63.626 +81.151 +77.169 +63.101 +30.57 +69.759 +92.996 +134.47 +191.73 +170.07 +85.207 +967.41 +10.064 +465.78 +856.99 +543.12 +128.59 +104.4 +509.09 +142.32 +30.173 +0.018056 +0.069506 +0.21218 +0.25674 +0.29171 +0.041781 +0.082685 +0.12274 +0.28577 +514.54 +1315.1 +1134.4 +362.18 +36.529 +5.7158 +13.332 +22.623 +42.637 +27.724 +269 +60.291 +139.61 +20000 +13.809 +0.095444 +0.022126 +0.028104 +0.077474 +0.1055 +0.10579 +0.055851 +0.015427 +0.038735 +0.31868 +0.31549 +323.86 +16.54 +63.47 +33.31 +75.162 +30.931 +49.124 +104.16 +28.062 +64.962 +122.33 +1827.4 +111.14 +125.46 +175.3 +306.12 +622.04 +332.1 +756.65 +332.29 +99.591 +97.807 +617.16 +237.91 +0.075459 +0.09817 +0.036888 +0.050964 +0.079193 +0.13119 +0.13242 +0.14494 +0.031957 +0.17187 +589.53 +1208.2 +631.15 +655.41 +28.047 +1.964 +8.8037 +9.9004 +54.197 +108.86 +292.79 +127.63 +80.943 +20000 +23.485 +0.29382 +0.29789 +0.19878 +0.33962 +0.068099 +0.079467 +0.007288 +0.037506 +0.28082 +0.24958 +0.5342 +138.92 +43.91 +80.864 +75.525 +33.456 +43.745 +35.243 +68.509 +242.97 +111.28 +665.75 +1173.1 +293.92 +63.573 +117.11 +65.458 +437.87 +2401.5 +322.46 +248.79 +0.22628 +0.31325 +0.029867 +0.055075 +0.33352 +0.10808 +0.097961 +0.050965 +0.097559 +0.26001 +0.10609 +0.22272 +0.19604 +0.4478 +0.04884 +2688.5 +517.31 +1947.1 +2998.4 +3050.5 +19.024 +12.228 +36.285 +111.83 +933.51 +384.9 +9.5006 +6.9376 +32.749 +0.14588 +0.63414 +0.23036 +0.19989 +0.096949 +0.13617 +0.17872 +0.22419 +0.49506 +0.1051 +0.23654 +84.427 +69.478 +44.515 +66.773 +22.462 +24.596 +25.031 +51.575 +86.672 +89.458 +274.77 +1748.2 +347.16 +86.336 +160.91 +340.79 +905.96 +918.58 +895.08 +642.69 +0.61904 +0.26566 +0.022074 +0.009777 +0.038808 +0.046555 +0.049495 +0.072805 +0.039843 +412.94 +526.09 +127.76 +681.57 +1018.9 +2207.2 +3223 +460.75 +1377.1 +2722.3 +1138.6 +646.42 +8.875 +19.774 +160 +1286.4 +791 +533.6 +6.5705 +0.093492 +0.22165 +0.15121 +0.10654 +0.031967 +0.096837 +0.18621 +0.33583 +0.58797 +0.61404 +951.81 +750.49 +104.87 +48.109 +32.955 +53.962 +46.786 +15.958 +44.103 +1.6119 +3.2856 +109.51 +557.3 +439.74 +346.32 +119.83 +730.12 +422.69 +34.31 +547.07 +961.38 +1593.4 +657.75 +581.54 +0.086168 +0.016832 +0.14373 +0.036174 +0.12091 +718.86 +371.35 +523.68 +454.24 +395.61 +136.23 +74.243 +199.85 +2667 +339.19 +987.6 +1520.3 +1379.8 +699.36 +137.48 +65.923 +121.29 +1393 +530.65 +475.79 +263.41 +48.472 +0.14855 +0.070753 +0.16731 +0.46154 +0.46442 +0.60423 +0.70573 +0.62273 +0.59138 +2110.8 +644.45 +96.967 +24.153 +46.224 +80.647 +100.5 +22.023 +98.255 +2.7744 +3.3778 +1.4647 +407.64 +477.95 +109.45 +72.38 +0.18236 +704.03 +34.932 +45.493 +70.09 +1557.5 +1527.5 +945.92 +353.64 +0.009963 +0.078112 +0.015346 +1543.1 +814.47 +205.55 +734.18 +586.54 +0.22841 +195.42 +25.252 +4308.7 +2982.5 +381.27 +911.22 +1223.6 +1845.3 +804.02 +256.27 +114.24 +449 +790.84 +371.47 +358.03 +72.74 +111.62 +114.86 +0.092551 +0.33198 +0.24754 +2.024 +0.25662 +0.45082 +0.73555 +3636.6 +1332.3 +736.46 +38.128 +14.932 +75.837 +145.37 +49.5 +30.549 +106.6 +4.1381 +3.8719 +4.404 +55.712 +140.15 +113.51 +110.97 +275.25 +53.031 +27.742 +28.972 +791.02 +1455.2 +803.03 +850 +187.82 +107.59 +0.027439 +406.67 +1281.1 +704.42 +392.19 +472.2 +0.36087 +0.13702 +108.82 +48.818 +2490.1 +1403.5 +598.74 +1206.4 +703.75 +2806.5 +904.82 +339.44 +266.8 +644.84 +1400.6 +213.52 +141.4 +64.925 +59.615 +218.05 +143.68 +156.46 +0.48526 +0.10011 +0.11582 +0.73423 +1.2026 +1077.8 +2833.8 +16.095 +53.049 +132.48 +81.803 +69.067 +23.986 +49.768 +9.1437 +5.7868 +5.7691 +4.7154 +25.75 +67.965 +96.853 +242.67 +299.44 +51.551 +870.16 +1561.1 +542.65 +1431.2 +1150.8 +573.67 +195.28 +120.62 +0.023145 +870.83 +1111.1 +1623.7 +689.16 +0.3522 +0.27709 +0.1833 +84.574 +9416.9 +1964.3 +1223.8 +985.14 +1189.1 +463.23 +2388.6 +339.1 +599.4 +42.319 +24.308 +1690.2 +454.07 +242.87 +92.49 +73.505 +260.17 +109.93 +87.11 +108.57 +0.25691 +0.10643 +0.5489 +0.29398 +1.0334 +0.76915 +23.035 +50.295 +112.1 +42.311 +58.278 +32.938 +56.575 +20.429 +17.221 +4.8275 +3.405 +26.037 +109.89 +262.45 +308.71 +460.05 +424.02 +759.79 +1671.8 +336.06 +494.13 +717.63 +681.86 +289.17 +190.57 +0.18026 +711.92 +1083.2 +1827.5 +1171.1 +524.14 +0.061159 +0.031658 +605.27 +3347.5 +1701.1 +844.35 +456.99 +252.33 +316.51 +1033.5 +289.16 +70.727 +135.95 +582.36 +3156 +436.38 +248.56 +434.39 +52.032 +252.51 +129.67 +64.451 +71.064 +43.197 +0.029187 +0.072202 +0.38776 +2.4376 +181.32 +26.303 +42.276 +129.77 +32.753 +29.461 +99.841 +57.437 +28.765 +16.319 +8.3125 +7.3448 +23.654 +0.20924 +341.65 +422.03 +888.55 +534.11 +0.052916 +2180.4 +554.26 +218.29 +663.52 +1142.7 +817.44 +181.83 +0.089715 +0.032828 +947.58 +770.61 +1104.5 +1372.5 +678.25 +0.03667 +2659.3 +4856.2 +108.41 +123.03 +385.33 +379.59 +289.76 +250.33 +44.122 +260.79 +406.53 +1078.2 +3163.8 +273.69 +143.51 +168.7 +161.71 +171.2 +83.715 +82.244 +82.581 +57.142 +84.223 +0.058064 +0.018525 +0.39208 +0.15717 +16.971 +26.239 +52.178 +14.793 +118.26 +87.222 +61.228 +19.653 +30.895 +16.039 +13.371 +0.076717 +0.042508 +0.14078 +368.6 +666.25 +390.75 +501.48 +1717.7 +227.22 +241.15 +1341.2 +2700.1 +1806.7 +0.19326 +0.62515 +0.083615 +0.068975 +1131.9 +1615.2 +1545.7 +2075.8 +2324 +0.1476 +6878.3 +90.707 +312.39 +208.75 +242.32 +233.34 +151.02 +500.75 +388.44 +272.79 +1254.3 +4917.3 +98.984 +180.57 +198.4 +57.886 +259.46 +261.01 +67.35 +39.523 +42.377 +68.401 +157.25 +0.01787 +0.093927 +180.75 +30.16 +22.477 +30.127 +17.203 +136.04 +33.182 +39.505 +30.61 +43.289 +28.315 +12.101 +0.051425 +0.11961 +0.062837 +404.75 +513.94 +507.17 +864.34 +545.76 +211.6 +321.55 +1383.1 +0.083571 +0.14291 +0.054787 +0.060374 +0.078012 +0.13783 +0.18706 +0.033564 +1573.2 +1813.8 +1907 +165.69 +81.013 +34.524 +163.51 +116.98 +94.782 +221.14 +1203.7 +794.01 +199.88 +328.06 +84.876 +134.85 +307.53 +117.17 +91.555 +149.31 +160.97 +256.08 +534.92 +40.635 +52.465 +52.969 +97.493 +0.016214 +0.036701 +234.14 +24.63 +58.414 +40.832 +18.311 +128.47 +33.194 +52.25 +12.694 +16.668 +32.631 +0.067626 +0.070366 +0.044752 +0.034006 +0.027681 +658.06 +758.61 +390 +426.88 +510.17 +464.74 +0.13617 +0.061527 +0.087851 +0.020834 +0.045807 +0.4487 +0.084579 +0.11244 +0.15476 +0.15494 +419.6 +284.29 +119.32 +93.848 +84.025 +223.19 +177.65 +6307.8 +507.65 +3118.7 +911.39 +391.22 +679.23 +100.11 +126.79 +283.41 +173.7 +113.68 +225.72 +131.52 +225.97 +817.71 +348.18 +372.26 +57.65 +90.304 +20.171 +516.09 +247.33 +63.356 +74.041 +24.325 +8.2242 +58.143 +22.833 +78.461 +18.696 +40.656 +28.866 +93.915 +0.011003 +0.073427 +4526 +10336 +494.75 +304.54 +1025 +237.63 +0.002272 +0.005741 +0.060402 +0.14137 +0.20482 +0.10709 +0.083907 +0.0853 +0.10609 +0.037686 +0.067858 +318.77 +273.43 +400.58 +150.08 +411.98 +51.441 +409.36 +565.16 +1434.6 +299.26 +2137.7 +734.81 +324.33 +967.01 +102.8 +120.28 +180.99 +0.086837 +0.033348 +0.008534 +96.816 +193.99 +313.71 +956.59 +718.23 +850.96 +178.73 +0.1603 +910.03 +183.92 +98.902 +80.227 +24.142 +0.020188 +23.907 +14.608 +28.496 +29.781 +22.497 +77.264 +159.32 +1591.7 +2224.3 +2747.5 +7564.6 +412.89 +493.36 +502.46 +0.012131 +0.008558 +0.026392 +0.085925 +0.1077 +0.071627 +0.094142 +0.046302 +0.048062 +0.034325 +0.21603 +300.71 +177.25 +211.43 +427.51 +146.06 +442.42 +975.6 +335.97 +967.08 +2985.5 +60.42 +54.068 +704.03 +0.02306 +1035.3 +176.47 +127.3 +0.019727 +0.29127 +0.068753 +0.027058 +2487.6 +104.35 +292.43 +1463 +259.57 +170.55 +0.15116 +492.86 +539.76 +457.75 +102.31 +55.297 +38.528 +6.612 +15.844 +7.7647 +14.473 +10.46 +17.294 +8942.5 +4122.4 +594.54 +802.4 +3440.1 +146.86 +126.7 +511.74 +601.7 +0.057692 +0.012538 +0.01099 +0.038868 +0.044684 +0.13979 +0.030668 +0.21989 +0.13407 +0.11574 +0.2496 +199.53 +114.29 +274.94 +33.134 +479.09 +450.39 +982.35 +304.81 +88.049 +209.88 +55.653 +31.25 +113.94 +445.04 +946.55 +151.36 +174.95 +0.049855 +0.13605 +226.8 +34.862 +738.82 +50.615 +1907.3 +996.84 +465.19 +85.041 +276.28 +181.44 +655.15 +919.45 +109.43 +37.833 +27.835 +6.7402 +15.373 +8.2221 +7.6279 +1380.1 +533.43 +194.9 +5635.1 +274.6 +235.42 +62.942 +78.698 +69.16 +0.007722 +0.13023 +0.049211 +0.010245 +0.020563 +0.022641 +0.091124 +0.15535 +0.19873 +0.29305 +0.33786 +0.10192 +0.042678 +0.020192 +23.556 +14.152 +45.576 +307.51 +136.5 +624.89 +858.12 +99.928 +151.83 +71.425 +25.967 +56.879 +472.13 +510.66 +352.05 +79.415 +0.17203 +218.25 +75.95 +56.997 +497.52 +27.933 +270.4 +669.57 +303.85 +105.2 +228.22 +122.79 +637.57 +303.92 +374.63 +245.07 +502.21 +680.14 +1623.2 +8.4624 +8.9577 +629.67 +0.061892 +8909.8 +159.49 +677.37 +153.96 +85.477 +45.226 +60.335 +0.10648 +0.18655 +0.22092 +0.012167 +0.030462 +0.015229 +0.028981 +0.048712 +0.43826 +0.252 +1.0217 +0.018653 +0.036854 +73.349 +16.855 +11.295 +26.129 +347.36 +322.43 +552.6 +890.92 +32.549 +43.508 +73.622 +24.926 +109.28 +238.14 +416.98 +188.04 +449.95 +398.66 +170.41 +79.815 +95.673 +0.27222 +0.18093 +0.099412 +728.63 +279.76 +106.08 +105.93 +114.35 +579.9 +145.47 +350.57 +326.93 +327.06 +404.72 +2442.8 +23.22 +0.13094 +1272.3 +0.061405 +948.63 +670.77 +125.22 +195.95 +34.767 +4.7996 +7.6113 +206.15 +20000 +0.085704 +0.024358 +0.058225 +0.026277 +0.12056 +0.12881 +0.095422 +0.20475 +0.1025 +261.33 +28.282 +79.353 +11.461 +14.806 +46.148 +381.07 +1339.5 +2644.2 +2204 +18499 +13.498 +49.602 +49.291 +104.11 +170.35 +330.54 +179.27 +468.26 +248.86 +294.03 +0.053086 +0.15638 +0.17896 +0.057096 +0.10409 +389.8 +278.98 +138.09 +251.28 +69.998 +487.99 +193.42 +498.54 +583.57 +304.76 +441.69 +795.82 +28.704 +4453.1 +309.73 +218.23 +598.49 +126.07 +191.18 +238.11 +151.22 +4.2604 +16.769 +8.6944 +46.896 +20000 +0.058789 +0.031753 +0.029668 +0.052241 +0.060219 +0.055602 +0.042411 +116.59 +141.78 +33.119 +49.46 +18.537 +107.1 +109.59 +453.53 +856.03 +1966.7 +4702.7 +10483 +21.285 +36.398 +48.881 +57.389 +1738.9 +540.17 +227.33 +630.35 +183.45 +226.62 +0.036326 +0.18052 +0.26416 +0.062086 +165.83 +545.48 +363.39 +98.071 +236.69 +114.21 +793.05 +477.92 +441.84 +267.67 +241.48 +472.05 +22.592 +0.35364 +141.98 +228.99 +224.72 +725.45 +82.94 +194.02 +189.35 +233.12 +489.4 +156.65 +8.6617 +132.28 +274.97 +169.6 +0.050915 +0.20541 +0.15962 +0.040473 +0.075542 +0.018255 +62.153 +123.03 +46.883 +42.171 +5631.1 +156.32 +66.638 +398.24 +674.13 +1072.3 +3557.2 +19321 +39.996 +28.732 +1360 +1106.8 +2210.8 +110.59 +66.505 +42.229 +200.82 +373.87 +595.05 +172.14 +279.86 +89.853 +139.81 +406.56 +220.54 +68.397 +113.36 +94.087 +1111.3 +324.35 +731.92 +95.594 +266.7 +62.053 +0.34574 +0.2113 +210.22 +337.77 +166.75 +9545.1 +62.981 +276.98 +349.55 +394.66 +634.95 +108.46 +0.13416 +107.17 +152.83 +338.19 +364.16 +519.42 +0.07794 +0.033883 +0.2838 +0.19881 +69.799 +49.651 +25.233 +25.888 +114.23 +52.859 +129.04 +423.46 +474.19 +1418.7 +2605 +14113 +6876.4 +632.08 +0.092299 +0.14075 +31.368 +110.51 +51.841 +23.413 +70.669 +550.1 +466.24 +118.63 +261.82 +77.011 +244.97 +433.74 +323.13 +397.83 +86.997 +482.12 +739.15 +143.05 +334.83 +0.10281 +0.22904 +0.15238 +0.022898 +0.097099 +205.89 +566.19 +99.629 +183.24 +74.231 +489.25 +531.23 +396.59 +1122 +528.96 +0.051827 +0.083037 +229.91 +319.65 +531.87 +430.27 +732.83 +7.0731 +0.06587 +0.10876 +75.451 +58.959 +30.712 +16.583 +50.468 +59.804 +154.15 +251.82 +468.08 +1276.3 +1122.8 +8582.5 +10320 +3300.7 +0.15433 +0.20388 +0.63893 +0.18157 +52.929 +24.673 +545.4 +274.18 +278.55 +75.689 +116.33 +162.69 +268.68 +551.12 +0.19239 +0.11292 +60.657 +434.49 +979.98 +21.284 +19.879 +0.099067 +0.27608 +0.11631 +0.30046 +211.34 +202.58 +258.79 +45.264 +203.56 +153.83 +614.78 +936.77 +935.1 +979.13 +0.42986 +0.23606 +0.2249 +0.40697 +369.44 +514.15 +197.64 +180.6 +21.749 +27.009 +17.92 +57.311 +21.804 +23.169 +30.378 +162.28 +143.9 +313.23 +379.54 +711.43 +1728.3 +1246.5 +3557.4 +14315 +4393.6 +0.045182 +0.10496 +141.78 +220.48 +98.791 +352.79 +813.81 +261.83 +233.61 +31.084 +0.065815 +0.16378 +0.2224 +0.20522 +0.23151 +110.96 +75.017 +0.053733 +34.637 +34.584 +25.741 +0.060038 +0.47984 +0.18324 +0.17818 +0.14935 +440.01 +144.25 +90.102 +7591.9 +2420.2 +469.07 +994.25 +256.92 +386.32 +0.4726 +0.2206 +0.10404 +0.25653 +0.21994 +491.04 +171.67 +449.13 +171.95 +14.905 +15.409 +51.898 +18.941 +8.0037 +46.097 +219.13 +210.1 +455.97 +220.09 +0.032572 +1991.2 +1630.7 +7786.8 +20000 +10464 +9506.7 +476.34 +323.28 +125.83 +109.16 +214.58 +521.41 +157.49 +281.17 +7353.2 +0.028334 +0.12307 +0.049167 +0.050323 +0.060093 +0.085251 +0.10346 +0.03905 +0.060784 +68.62 +48.841 +51.48 +55.646 +172.46 +435.81 +564.81 +238.47 +253.22 +55.839 +106.42 +213.26 +1892.6 +1061.9 +427.01 +275.19 +231.97 +0.66456 +0.14827 +0.26272 +0.10371 +0.2377 +165.92 +156.79 +154.46 +16.875 +23.637 +77.109 +27.485 +6.6853 +80.203 +161.46 +342.98 +45.325 +85.355 +0.10149 +634.3 +1968.6 +9329.9 +10999 +2855.7 +11456 +400.77 +1128.2 +70.43 +0.16392 +576.76 +1125.1 +135.97 +191.64 +4497.4 +1402.9 +0.13357 +0.064486 +0.065728 +0.069227 +0.02709 +0.077618 +0.035601 +0.026241 +0.069374 +52.44 +156.85 +15.385 +265.81 +707.69 +1896.8 +1876.6 +122.75 +48.43 +326.29 +163.61 +0.24287 +0.48659 +536.6 +517.08 +269.23 +0.18578 +0.16186 +0.2275 +0.065137 +0.36187 +0.13932 +358.77 +340.26 +505.36 +81.75 +82.705 +20.117 +19.797 +157.64 +279.37 +142.96 +44.14 +0.15828 +922.11 +755.57 +922.31 +14702 +13445 +1706 +12244 +15940 +0.073185 +0.22957 +49.04 +447.54 +320.07 +116.87 +261.78 +938.64 +1081.3 +0.20777 +0.12221 +0.18277 +0.10492 +0.029754 +0.093913 +0.27934 +0.080188 +0.12469 +37.618 +60.276 +80.551 +101.44 +47.278 +1058.1 +3053.7 +121.17 +76.871 +195.09 +107.5 +122.78 +0.30328 +0.68965 +501.64 +134.37 +53.823 +0.09565 +0.018662 +0.11248 +0.063694 +0.29031 +421.38 +525.67 +399.43 +160.19 +45.561 +30.058 +20.207 +189.46 +259.87 +159.38 +330.54 +120.43 +1131.4 +535.07 +998.61 +18824 +11549 +2342.9 +10327 +11622 +20000 +100.18 +138.46 +174.17 +197.57 +131.49 +35.636 +859.09 +755.13 +0.12208 +0.06326 +0.17272 +0.16701 +0.074919 +0.28059 +0.097066 +78.622 +28.389 +51.072 +35.034 +59.461 +19.288 +103.09 +88.101 +4344.6 +0.082997 +47.989 +543.78 +182.17 +222.24 +0.20307 +0.33123 +1.1954 +125.88 +187.31 +245.27 +0.074553 +0.080342 +0.14937 +0.060376 +551.16 +343.73 +552.14 +154.86 +81.622 +28.188 +19.149 +114.79 +167.95 +55.014 +100.81 +281 +570.48 +246.54 +913.15 +902.89 +0.28008 +2308.8 +8697 +18408 +19984 +16036 +222.52 +74.515 +92.665 +69.826 +45.865 +967.5 +0.10053 +0.047957 +0.2536 +0.31526 +0.48919 +0.14268 +0.61258 +29.592 +170.92 +58.489 +98.876 +15.002 +67.972 +273.48 +109.28 +72.592 +36.251 +0.20465 +0.073255 +416.49 +355.74 +330.01 +108.41 +0.31262 +0.24472 +0.50086 +289.54 +305.19 +392.76 +0.046269 +1364.5 +1327.8 +1237.5 +328.25 +443.09 +198.19 +75.954 +30.309 +25.599 +141.79 +96.878 +75.471 +46.122 +16.209 +462.37 +171.34 +1103 +60.938 +0.18159 +2799.2 +5734.3 +20000 +8483 +14129 +3510.5 +55.485 +114.45 +137.68 +23.673 +0.14777 +0.070849 +0.1263 +0.16507 +0.12828 +0.10689 +0.08366 +0.41969 +12.148 +350.06 +102.6 +137.85 +25.573 +116.32 +917.42 +474.11 +87.351 +35.026 +0.024031 +0.077738 +419.87 +456.46 +370.93 +198.7 +0.20856 +0.20605 +0.37574 +0.24119 +0.12551 +304.4 +380.06 +66.674 +71.871 +80.959 +154.45 +174.2 +120.15 +112.93 +30.151 +849.27 +883.1 +68.032 +39.522 +21.946 +16.395 +60.955 +114.05 +474.19 +33.016 +9.7092 +2993.5 +3237.1 +11553 +8108.9 +6792.4 +6191.8 +39.122 +101.54 +193.04 +0.036409 +0.24783 +0.39837 +0.050049 +0.13898 +0.071489 +0.15832 +0.12409 +0.024948 +0.02717 +452.57 +94.975 +125.14 +183.78 +212.71 +459.83 +1083.7 +783.08 +31.626 +34.915 +1104.8 +846.78 +587.09 +493.19 +353.47 +295.52 +329.9 +501.04 +218.75 +63.826 +235.55 +39.531 +76.067 +102.75 +0.025146 +0.081144 +0.033627 +0.017223 +181.02 +15.509 +173.78 +389.62 +396.68 +613.92 +28.719 +23.036 +46.045 +77.145 +85.617 +42.264 +13.291 +29.488 +2690.1 +10504 +10224 +6468.9 +7848.9 +5778.2 +116.14 +255.67 +0.046071 +0.23661 +0.23892 +0.26159 +0.36131 +0.015283 +0.18383 +0.047899 +0.03856 +0.032439 +0.27664 +109.79 +172.77 +168.4 +113.13 +24.335 +173.53 +48.974 +48.538 +2315.7 +1026.2 +840.83 +551.05 +313.03 +249.76 +344.58 +307.28 +135.96 +177.99 +428.03 +0.043837 +0.41669 +2624.1 +762.69 +727.96 +0.046257 +0.14633 +0.075508 +182.56 +34.696 +96.186 +131.53 +420.43 +1467 +143.31 +8.5592 +50.311 +47.216 +43.768 +240.3 +107.82 +29.467 +1813.8 +3962 +8994.7 +5268.8 +7004.7 +3779.8 +78.952 +246.37 +0.12059 +0.075028 +0.15795 +0.15238 +0.27144 +0.098843 +0.0699 +0.213 +0.15767 +0.381 +0.60497 +799.89 +107.68 +99.013 +71.833 +75.325 +206.53 +37.644 +38.616 +1900.7 +609.88 +637.64 +918.04 +90.394 +481.77 +221.92 +187.56 +0.2294 +0.46302 +0.06562 +0.031653 +267.83 +1186.8 +795.53 +370.82 +0.077734 +0.03083 +0.043048 +174.83 +54.818 +52.029 +76.192 +188.3 +319.68 +120.25 +238.01 +191.25 +38.755 +158.48 +135.68 +181.29 +406.91 +282.7 +3311.4 +4814.6 +3585.9 +7761.7 +3881.2 +846.31 +0.086949 +0.10202 +0.052249 +0.28253 +0.10332 +0.18271 +0.10702 +0.17144 +0.55987 +0.15518 +2.0496 +73.8 +133.71 +126.26 +155.91 +94.883 +90.031 +119.32 +35.375 +1227.9 +2271.3 +550.51 +98.403 +85.911 +83.981 +0.29934 +0.13344 +0.14333 +0.077316 +0.12509 +0.064666 +0.10513 +274.43 +1265.3 +983.17 +0.051347 +0.018314 +0.091159 +0.019621 +0.099907 +1.0825 +51.356 +86.534 +100.99 +312.72 +532.08 +391.66 +228.79 +34.181 +125.81 +298.69 +437 +689.64 +354.82 +5237.1 +11255 +3628.4 +9770.9 +5856.3 +1778.5 +0.13399 +0.023454 +0.087332 +0.037313 +0.15404 +0.048491 +0.052891 +0.061447 +0.22213 +43.282 +67.874 +116.76 +72.129 +54.182 +63.863 +122.55 +162.21 +81.504 +20.63 +33.49 +4785.4 +1832.1 +6520.8 +162.25 +91.154 +0.14583 +0.15027 +0.08683 +0.023238 +0.020849 +0.46043 +229.6 +379.55 +811.65 +1626.5 +0.039916 +0.012936 +0.13504 +0.0431 +0.60974 +0.46007 +0.064702 +82.252 +143.08 +632.33 +501.52 +488.26 +270.64 +7.6214 +90.725 +125.28 +936.31 +763.32 +624.63 +549.46 +2602.5 +1461.7 +9422.5 +11755 +3087.1 +4066.4 +0.082078 +0.061463 +0.035707 +0.44105 +0.053522 +0.089714 +0.039575 +55.468 +28.521 +117.1 +203.69 +202.94 +147.25 +157.56 +380.54 +108.5 +97.104 +163.15 +92.388 +4457.4 +5335.4 +6532.4 +5788 +0.33996 +0.45049 +0.49725 +0.20038 +0.42904 +0.071308 +267.39 +164.13 +488 +701.77 +0.085081 +0.044189 +0.026306 +0.11488 +0.20757 +201.13 +0.10324 +0.020678 +0.20478 +184.35 +605.83 +519.96 +460.74 +485.89 +622.06 +422.35 +159.38 +3313.4 +352.9 +935.27 +1279.9 +1473.4 +2156.4 +1300.5 +4967.8 +3252.6 +4246.7 +1252.4 +0.052149 +0.3079 +67.434 +75.049 +320.34 +58.434 +99.523 +57.999 +137.92 +65.159 +153.36 +541.38 +209.39 +357.34 +110.93 +129.27 +142.69 +93.651 +312.27 +10347 +11399 +9693.4 +2540.1 +0.19946 +0.38728 +38.135 +139.72 +527.38 +305.19 +194.73 +582.86 +0.25537 +0.45171 +0.29298 +0.13606 +0.069507 +0.096938 +127.4 +0.067033 +0.08114 +0.072745 +234.64 +921.34 +671.36 +259.89 +613.15 +535.76 +325.93 +2210.8 +3704.4 +64.302 +3399.2 +1954.2 +1198 +1236.4 +771.21 +907.98 +118.77 +60.177 +57.668 +57.181 +166.76 +132.06 +128.17 +430.11 +83.075 +664.71 +189.25 +93.583 +33.572 +17.382 +27.138 +0.15643 +98.319 +58.568 +139.78 +145.37 +214.59 +202.92 +11568 +9209.5 +56.101 +33.927 +21.344 +216.71 +84.914 +151.41 +591.12 +0.034204 +0.042723 +0.12519 +0.26055 +0.041349 +0.62342 +0.31893 +0.017328 +0.18152 +87.708 +0.11709 +0.12679 +0.065251 +427.03 +132.26 +658.26 +406.39 +608.25 +237.26 +148.45 +609.6 +120.12 +54.01 +7079.5 +6846.2 +1047.2 +1231.4 +518.96 +17.765 +16.125 +71.669 +33.905 +38.618 +111.37 +40.705 +0.24985 +528.05 +309.16 +360.2 +331.01 +77.411 +41.965 +0.31075 +0.31499 +0.63556 +46.76 +90.775 +71.922 +166.56 +211.69 +647.67 +158.57 +67.439 +47 +33.179 +54.502 +132.33 +217.83 +0.33456 +0.4556 +0.16832 +0.039423 +0.01732 +0.031499 +0.14294 +0.30992 +0.082471 +0.061064 +0.086414 +161.11 +0.24199 +94.826 +7.5736 +160.47 +46.843 +62.732 +248.94 +255.64 +145.1 +167.18 +1431.5 +96.352 +188.22 +151.82 +7009.8 +955.22 +23.798 +5.8709 +15.955 +67.27 +61.509 +173.23 +3467.1 +3358.1 +340.26 +0.1087 +175.6 +347.31 +409.32 +181.72 +0.020412 +0.43702 +0.23997 +0.19749 +1087.6 +739.29 +258.94 +114.74 +175.14 +24.965 +590.07 +191.2 +160.37 +119.23 +56.37 +48.726 +2694.9 +0.17876 +0.29649 +0.27614 +0.11797 +0.041392 +0.029639 +0.059356 +0.43379 +0.2951 +0.06078 +0.073678 +0.09094 +110.14 +0.032875 +72.236 +12.499 +119.4 +43.02 +1212.4 +197.09 +91.781 +66.608 +165.16 +571.38 +189.41 +87.048 +12131 +8930.2 +544.84 +16.451 +7.6139 +10.072 +385.99 +414.53 +331.22 +2722.3 +3730.4 +726.2 +0.066391 +293.48 +319.4 +286.56 +198.93 +0.21951 +0.30589 +0.22702 +0.35649 +1128.2 +1270.1 +795.65 +621.67 +245.36 +55.523 +45.343 +242.87 +102.26 +135.57 +95.17 +1105.7 +3243.5 +2443.7 +0.12618 +0.039646 +0.092272 +0.019015 +0.049392 +0.13788 +0.29458 +0.38693 +0.11744 +0.14648 +0.10673 +0.0909 +0.14405 +0.052876 +16.981 +29.422 +19.697 +266.75 +251.86 +135.32 +39.383 +235.9 +391.03 +130.08 +15.036 +17.366 +5406.4 +664.88 +900.34 +3.0586 +6.2398 +37.197 +454.16 +386.48 +3780.2 +3191.3 +0.064868 +0.12711 +314.4 +489.83 +754.37 +498.65 +0.036711 +0.16258 +0.17232 +0.18831 +2229.8 +1412.8 +1410.5 +324.31 +231.47 +34.193 +13.419 +9.1415 +12.812 +195.79 +107.12 +133.26 +1748.8 +906.83 +0.19532 +0.23695 +0.314 +0.1709 +0.14633 +0.20825 +0.15526 +0.29746 +0.32529 +0.072272 +0.089327 +260.09 +0.063145 +93.052 +9.6554 +25.427 +17.852 +221.4 +194.89 +172.49 +30.199 +249.35 +379.56 +763.34 +186.2 +26.149 +3026.2 +692.78 +723.21 +315.18 +3.0772 +21.304 +393.17 +246.61 +4271.9 +0.060919 +0.046626 +0.029377 +654.32 +333.56 +1338.4 +1098.4 +0.11303 +0.90226 +1.3895 +3366.2 +2411.3 +1054.4 +1000.3 +277.56 +153.2 +34.629 +30.943 +14.62 +13.599 +36.955 +70.606 +88.729 +47.73 +907.49 +1619.4 +0.069392 +0.053491 +0.2081 +0.082038 +0.31546 +0.16645 +0.18893 +0.97556 +0.13254 +0.043768 +733.47 +547.99 +161.23 +50.288 +9.3552 +53.824 +154.03 +75.496 +102.25 +55.905 +433.64 +933.58 +852.92 +32.672 +852.94 +421.81 +685.36 +602.51 +314.85 +109.95 +26.05 +3.2997 +357.36 +0.053596 +0.053042 +0.056365 +0.071051 +0.059369 +290.48 +1081.4 +1135.5 +0.3802 +203.72 +297.87 +2148.7 +1160.7 +1972.9 +698.74 +42.374 +52.705 +18.381 +15.618 +12.723 +11.885 +25.529 +41.156 +111.99 +45.488 +1386.9 +1187.6 +0.085396 +0.22767 +0.079375 +0.41602 +0.45795 +0.13486 +0.23069 +0.17411 +0.073808 +0.039912 +951.34 +180.92 +42.837 +44.92 +13.294 +44.696 +74.187 +30.373 +92.036 +28.542 +486.42 +447.17 +1746.4 +3610.7 +1197.2 +244.98 +480.04 +1316 +438.55 +148.34 +127.92 +2.4026 +4.301 +7.3373 +5.1145 +0.1194 +0.23882 +0.054546 +520.7 +1099.1 +3755.4 +2360.6 +1544.9 +334.44 +2940.2 +2360.2 +1715.7 +88.508 +98.399 +69.571 +27.698 +21.688 +16.703 +11.3 +13.157 +60.59 +41.459 +59.17 +2544.4 +842.38 +1049.9 +0.31323 +0.55603 +0.10551 +0.29991 +0.024167 +0.016651 +0.052495 +0.094912 +0.18037 +191.82 +158.57 +122.34 +66.923 +21.741 +68.479 +112.96 +876.82 +582.08 +982.02 +538.5 +5203.7 +2959.4 +3914.2 +501.39 +293.79 +870.55 +2222.3 +619.4 +1147.8 +327.87 +258.82 +4.7098 +1.8105 +8.2864 +3.3241 +0.15997 +0.33156 +0.20342 +1462.9 +4944.5 +5239 +1275.5 +214.71 +1638.8 +5050.7 +1614.2 +84.125 +94.556 +44.072 +15.984 +36.715 +27.435 +6.5033 +10.267 +91.466 +59.405 +968.65 +2216.9 +832.26 +1054.5 +651.58 +0.19969 +0.18527 +0.054305 +0.10823 +0.037332 +0.027316 +0.082641 +0.13353 +290.28 +417.81 +91.493 +93.026 +23.152 +73.085 +1171.5 +583.13 +554.53 +5963.4 +4200.4 +2515.3 +6321 +4449.1 +1047.5 +460.64 +1966.2 +683.61 +555.77 +1028.4 +280.78 +244.74 +510.85 +3.254 +4.3246 +7.8743 +5.6469 +186.84 +678.8 +1366.3 +3388.3 +2437.8 +1217.1 +1138.4 +1947.5 +5538.5 +111.19 +78.119 +65.127 +36.123 +14.116 +13.35 +11.48 +4.6086 +12.245 +24.563 +1434.5 +407.44 +762.2 +469.99 +616.19 +488.6 +0.17245 +0.13277 +0.068116 +0.53689 +0.080141 +0.21701 +0.064639 +0.43209 +205.5 +292.56 +141.74 +144.65 +52.802 +147.63 +2286.2 +1123.9 +1103.6 +1604.4 +5023.1 +2617.7 +3409.5 +7741.7 +818.84 +1323.4 +3132.8 +731.03 +394.11 +619.52 +552.56 +455.54 +631.72 +0.39564 +0.26183 +16.051 +19.122 +117.11 +200.16 +943.09 +4720.9 +1936.3 +1225 +633.51 +11.427 +18.259 +99.629 +28.145 +46.964 +28.572 +8.9142 +15.233 +5.3705 +3.1412 +6.8421 +0.037312 +4069.8 +697.2 +460.84 +347.69 +639.37 +304.68 +0.10547 +0.27055 +0.11715 +52.078 +0.041982 +0.2702 +0.059777 +0.13009 +408.22 +550.12 +296.14 +289.4 +115.23 +179.51 +876.69 +767.14 +2202.2 +2010.4 +5082.8 +3432 +2299 +2044 +573.66 +335.86 +1015.9 +444.93 +442.93 +519.13 +200.91 +234.86 +1166.4 +0.10979 +134.56 +118.02 +33.468 +10.456 +16.116 +93.107 +211.61 +908.18 +1614 +542.83 +18.869 +18.769 +61.91 +25.595 +33.321 +32.171 +7.3741 +4.9261 +3.7732 +7.7995 +0.15224 +0.049007 +0.21298 +743.64 +716.26 +234.54 +281.05 +320.82 +0.079058 +0.049581 +0.056477 +0.058339 +121.73 +88.976 +142.79 +0.084129 +358.96 +714.44 +473.74 +495.39 +111.94 +214.81 +1482.5 +1608.2 +1560.5 +996.76 +5466.6 +7466.3 +860.15 +34.31 +76.165 +376.09 +940.98 +648.1 +259.02 +343.05 +237.32 +429.58 +1284.2 +0.35656 +203.06 +92.915 +38.74 +1952.8 +57.5 +16.034 +15.171 +144.9 +146.6 +386.64 +13.552 +25.337 +49.745 +9.3368 +32.106 +21.814 +10.057 +8.3833 +3.4628 +0.31986 +0.44443 +0.031781 +0.24833 +483.19 +701.32 +354.28 +192.43 +209.7 +237.15 +0.036185 +0.10056 +0.071706 +266.71 +84.15 +90.284 +325.55 +730.94 +663.1 +561.57 +391.81 +90.439 +0.015546 +3261.2 +1657.2 +1785 +1281 +4926.5 +7388 +189.66 +47.789 +111.6 +385.84 +826.85 +733.14 +770.03 +1389.6 +720.64 +942.37 +0.094865 +0.34804 +361.38 +44.217 +52.052 +55.382 +55.763 +135.04 +11.165 +46.845 +155.18 +84.62 +14.106 +27.621 +30.876 +32.422 +23.38 +6.5055 +5.5295 +0.032178 +0.067851 +0.92011 +0.10991 +0.35937 +0.36764 +253.72 +204.32 +261.34 +132.96 +121.03 +164.39 +0.063615 +0.30102 +0.039288 +0.060661 +287.73 +130.21 +315.86 +1012.5 +406.59 +967.14 +466.26 +67.718 +415.6 +2500.3 +1952.1 +1514.4 +1331 +6187.9 +37.46 +122.8 +65.286 +64.479 +572.95 +525.35 +587.39 +974.17 +3823.8 +458.61 +83.664 +0.13177 +71.58 +270.96 +48.323 +97.772 +60.059 +43.288 +170.48 +688.02 +166.21 +234.4 +103.27 +29.945 +115.2 +54.189 +21.057 +11.543 +6.9722 +0.054221 +0.036881 +0.20741 +0.12757 +0.082005 +0.20037 +0.19051 +265.27 +347.57 +478.71 +145.93 +106.95 +125.97 +180.21 +0.37074 +0.3512 +0.11881 +782.51 +118.94 +190.28 +2246.3 +1446.3 +1310.1 +643.15 +392.78 +473.62 +2065.7 +3092.9 +848.06 +1078 +3044.3 +39.578 +89.87 +103.36 +113.57 +782.41 +953.63 +143.16 +711.19 +102.85 +89.746 +94.361 +0.020802 +83.937 +109.24 +71.171 +89.005 +68.735 +85.852 +93.225 +338.5 +219.85 +119.01 +151.15 +49.583 +128.24 +235.5 +13.677 +3.9162 +3.4719 +0.036448 +0.016638 +0.10974 +0.025776 +0.17872 +0.051307 +409.19 +214.74 +170.31 +171.8 +178.89 +99.285 +121.7 +3.25 +0.46682 +0.27197 +0.038411 +0.11383 +220.85 +128.53 +3456.6 +2369.7 +133.38 +904.17 +868.23 +1260.2 +3292.2 +1504.7 +1165.8 +2589.1 +4327.9 +46.512 +130.75 +174.84 +127.76 +783.3 +287.67 +235.85 +575.19 +61.65 +104.44 +92.054 +78.274 +65.097 +20.35 +103.39 +81.509 +50.337 +45.021 +251.01 +142.09 +960.98 +161.4 +161.57 +97.999 +185.49 +176.66 +20.015 +6.2954 +525.24 +68.706 +0.22691 +0.066399 +0.057007 +46.673 +116.12 +534.63 +442.88 +392.69 +179.41 +152.85 +65.772 +0.095101 +0.25768 +0.033214 +0.17778 +0.014181 +0.060031 +0.16431 +20.129 +3236 +61.693 +343.21 +965.7 +834.12 +713 +3136.9 +2154.5 +1684.5 +2235.7 +190.79 +21.416 +97.067 +145.73 +297.62 +128.56 +168.29 +224.18 +70.085 +1201.3 +302.88 +240.3 +108.07 +61.823 +32.249 +85.159 +39.965 +388.2 +319.55 +413.41 +224.91 +768.18 +245.77 +665.64 +62.988 +148.35 +125.86 +154.12 +233.24 +447.69 +79.678 +58.148 +0.12035 +153.03 +70.147 +138.95 +338.78 +339.17 +206.98 +95.374 +119.32 +0.061426 +0.084487 +1.1804 +0.29996 +0.019248 +0.026253 +0.027998 +62.864 +24.047 +21.726 +64.381 +207.61 +189.7 +563.36 +1214.8 +3294.3 +1658 +2824.1 +86.644 +145.2 +27.612 +70.64 +106.62 +28.807 +43.086 +56.782 +3162.7 +1376.1 +1386.1 +118.63 +250.56 +156.23 +176.66 +544.03 +159.88 +146.33 +898.93 +198.91 +447.5 +353.27 +627.32 +341.92 +63.292 +68.802 +153.75 +153.29 +185.97 +153.71 +524.92 +416.46 +259.45 +0.027143 +393.46 +96.603 +59.025 +147.99 +236.23 +234.55 +165.65 +0.41817 +0.10333 +0.11642 +0.069868 +0.13281 +0.10186 +0.060185 +45.732 +60.076 +21.233 +36.585 +48.326 +130.62 +189.66 +845.24 +780.01 +1908.3 +208.62 +167.75 +90.478 +60.41 +897.06 +263.36 +56.516 +39.65 +705.76 +1966.9 +1397.9 +1315.7 +1115.8 +623.37 +232.61 +146.36 +385.61 +197.86 +159.9 +90.327 +653.81 +279.15 +440.25 +150.54 +324.71 +188.91 +131.97 +138.71 +76.791 +179.92 +60.628 +27.495 +40.028 +105.76 +26.723 +738.87 +414.74 +56.036 +114.41 +123.45 +194.09 +91.101 +184.3 +0.25979 +0.019588 +0.099334 +0.21981 +0.099103 +0.024215 +0.088715 +66.723 +103.2 +17.681 +42.349 +69.797 +190.81 +288.01 +990.07 +1043.5 +48.275 +12.072 +288.3 +50.763 +810.42 +31.41 +80.397 +28.468 +92.216 +466.96 +2019.2 +997.98 +1088.8 +812.79 +417.17 +180.77 +56.066 +159.04 +222.37 +176.28 +105.5 +1115.1 +344.83 +330.7 +106.94 +297.76 +186.75 +343.78 +343.12 +58.288 +246.61 +104.77 +40.482 +25.593 +60.988 +28.976 +317.12 +900.53 +110.85 +165.11 +295.52 +160.01 +109.18 +212.56 +0.22673 +0.047076 +0.056549 +0.27241 +0.14521 +0.039006 +34.946 +119.14 +68.839 +20.158 +26.525 +109.2 +84.181 +180.95 +107.23 +26.654 +41.926 +12.439 +20.542 +0.62664 +91.266 +60.013 +48.837 +26.944 +85.27 +844 +2678.3 +1574.1 +1237.7 +334.01 +461.17 +235.47 +113.44 +91.406 +191.4 +115.61 +125.97 +1193.8 +740.37 +286.37 +91.103 +542.14 +232.26 +539.56 +112.08 +120.87 +212.24 +85.426 +91.637 +32.967 +99.588 +12.455 +10.973 +407.4 +175.17 +286.11 +312.26 +355.07 +150.02 +238.14 +0.034484 +0.013058 +0.0192 +0.10105 +68.43 +53.583 +72.121 +68.19 +55.213 +30.108 +36.227 +171.6 +157.41 +3075.8 +964.19 +27.825 +68.663 +12.995 +10.282 +12.274 +172.28 +36.891 +87.62 +26.678 +637.13 +1510.6 +3177.3 +1644.3 +1406.2 +517.34 +507.96 +400.61 +200.69 +180.53 +73.393 +193.07 +173.73 +1250.9 +796.15 +576.58 +515.23 +259.83 +344.4 +481.8 +159.91 +74.569 +124.6 +74.994 +106.75 +22.688 +176.46 +12.388 +502.16 +349.64 +2976.5 +331.75 +333.69 +328.73 +182.37 +191.19 +743.18 +755.27 +0.03503 +0.10898 +29.441 +35.312 +35.826 +111 +70.684 +72.816 +55.644 +58.629 +101.67 +2471.6 +860.18 +766.9 +883.26 +25.6 +5.1439 +8.7378 +15.627 +33.325 +211.9 +60.397 +101.69 +1332.5 +3060 +4609.7 +1957.1 +212.12 +530.62 +459.73 +188.94 +107.74 +168.26 +140.91 +162.16 +627.7 +725.06 +1303.5 +418.4 +361.09 +553.24 +477.98 +257.37 +0.068583 +62.281 +74.97 +38.838 +24.013 +56.757 +13.842 +877.41 +633.51 +1581.6 +0.047724 +268.64 +458.73 +169.88 +80.418 +677.29 +695.39 +255.96 +37.205 +16.765 +49.366 +63.452 +57.471 +123.72 +170.14 +66.505 +65.926 +5430.1 +2961.3 +1700.5 +1172.6 +928.9 +1575.7 +0.21461 +9.7226 +24.895 +429.78 +234.85 +61.834 +249.54 +740.19 +3068.4 +5828.7 +1520 +1229 +491.2 +627.36 +75.631 +141.23 +285.98 +133.21 +178.42 +319.06 +308.66 +1294.3 +461.18 +447.44 +529.36 +654.58 +0.14097 +0.15739 +42.862 +43.728 +62.933 +14.411 +45.803 +8.4943 +435.44 +819.18 +0.072792 +0.038644 +0.012103 +0.19201 +118.95 +105.25 +945.04 +357.43 +241.32 +874.51 +10.599 +44.553 +95.873 +95.984 +92.944 +131.29 +47.153 +3520.4 +3212.7 +4248.5 +2582.6 +2092.5 +1678.6 +53.135 +0.069471 +7.6486 +53.938 +206.7 +110.02 +74.563 +424.97 +1881.9 +5918.7 +4586.8 +1687.3 +1662 +465.73 +622.63 +0.037337 +164.78 +293.03 +103.96 +327.39 +463.18 +471.76 +391.69 +211.72 +320.64 +344.15 +931.69 +0.094937 +0.0906 +35.584 +60.108 +41.609 +13.12 +15.302 +779.02 +363.35 +306.45 +0.089787 +0.030569 +0.033739 +0.64366 +114.74 +92.952 +387.66 +228.84 +112.24 +803.74 +332.45 +1272.9 +134.58 +71.012 +45.468 +119.03 +58.841 +267.25 +2309.6 +2630.8 +1756.5 +2424 +2443.7 +60.331 +0.11907 +0.14167 +63.106 +187.46 +104.66 +185.77 +186.8 +26.522 +9706.3 +3577.8 +1967.4 +924.07 +375.15 +582.36 +1425.1 +1132.3 +409.33 +100.11 +233.65 +281.67 +800.7 +381.51 +504.34 +423.49 +731.06 +410.49 +347.21 +0.074024 +0.019557 +42.297 +38.303 +9.8744 +18.558 +229.57 +248.25 +407.76 +0.26271 +0.06502 +0.12599 +0.15635 +0.094413 +253.74 +530.71 +347.99 +164.4 +1678.3 +645.46 +1617.5 +403.34 +56.769 +54.905 +204.75 +74.958 +136.17 +636.16 +1576.1 +3172.8 +5961.7 +1326.8 +868.74 +53.337 +52.886 +0.066584 +155.57 +116.53 +210.28 +112.91 +71.816 +5.6472 +3418.1 +1590.3 +541.64 +602.74 +393 +2265.5 +1488.6 +0.037064 +167.37 +276.11 +264.12 +279.67 +1058.9 +527.69 +521.93 +642.74 +713.74 +128.96 +1093.4 +37.365 +49.628 +28.63 +9.1692 +16.203 +177.19 +295.33 +95.657 +0.061756 +0.091459 +0.24849 +0.33318 +0.086877 +501.08 +1349.8 +823.09 +316.56 +1861.4 +1065.3 +718.59 +271.42 +346.54 +92.738 +142.07 +61.35 +312.77 +503.15 +356.05 +3065.2 +14441 +3915.6 +1743.8 +325.8 +88.939 +118.41 +0.15326 +140.31 +217.4 +174.92 +48.1 +8.0063 +1607.6 +1693.6 +440.18 +416.11 +167.17 +3106 +211.86 +211.42 +268.28 +264.78 +282.61 +318.27 +1025.1 +1196.8 +846.18 +375.89 +354.41 +233.28 +65.734 +26.272 +25.831 +39.663 +12.807 +533.47 +379.67 +368.2 +164.27 +0.078384 +0.11554 +0.082844 +0.31618 +553 +198.53 +723.76 +484.41 +442 +3142.8 +2471.6 +1773.3 +193.73 +241.07 +358.73 +211.15 +56.826 +255.63 +262.19 +741.48 +459.67 +12887 +6208.7 +3007 +386.33 +2103.1 +77.422 +160.82 +128.79 +217.44 +131.81 +101.89 +11.502 +1738.5 +822.3 +1040.2 +179.04 +103.33 +464.96 +66.585 +207.9 +277.95 +311.92 +449.82 +248.89 +812.64 +1627.6 +709.11 +453.64 +378.45 +491.83 +64.011 +29.601 +35.975 +29.799 +664.47 +297.62 +513.99 +722.17 +142.55 +0.20575 +0.058017 +0.15077 +207.84 +560.63 +454.59 +563.35 +1058.5 +351.9 +3496.2 +2501.5 +3437.6 +270.15 +457.24 +409.05 +249.73 +114.22 +213.91 +426.6 +297.57 +262.89 +938.64 +7730.1 +2040.3 +838.85 +1542.2 +168.08 +307.29 +143.34 +294.1 +212.66 +115.91 +9.7039 +12.762 +1601 +377.93 +597.62 +138.19 +171.62 +65.317 +231.28 +138.16 +302.66 +1388.8 +457.5 +614.03 +686.75 +638.82 +440.39 +120.63 +77.634 +76.019 +51.889 +76.537 +0.22543 +284.39 +352.74 +367.84 +547.59 +381.31 +0.13935 +0.25902 +203.51 +90.192 +273.14 +538.77 +424.09 +1983.5 +473.25 +2627.3 +1195.4 +5353.6 +1206.2 +532.9 +673.63 +165.7 +162.53 +141.46 +408.17 +317.96 +271.79 +753.58 +1009.3 +0.072567 +1032.2 +187.01 +311.51 +268.02 +126.12 +110.86 +189.38 +150.68 +33.989 +15.462 +231.63 +316.34 +380.13 +115.43 +130.05 +71.707 +562.86 +477.46 +527.93 +1558.3 +1960.3 +224.8 +525.93 +416.59 +191.89 +82.503 +140.25 +106.87 +57.258 +0.021598 +431.39 +455.88 +904.79 +550.3 +393.87 +423.39 +145.38 +51.405 +108.13 +51.997 +362.21 +364.75 +656.58 +2086.6 +528.73 +1289.6 +923.89 +2732.1 +331.25 +884.78 +341.21 +155.31 +149.71 +218.46 +119.18 +174.57 +452.53 +773.07 +679.24 +266.37 +142.94 +97.683 +380.37 +149.4 +134.4 +121.81 +500.84 +501.78 +67.229 +31.939 +462.75 +341.69 +879.5 +209.23 +55.529 +86.01 +82.324 +928.47 +291.68 +522.37 +1145 +306.36 +218.21 +705.79 +134.13 +151.92 +179.66 +97.813 +24.116 +0.010359 +0.010067 +1127 +1205.6 +656.76 +620.3 +267.97 +216.94 +88.884 +165.88 +98.846 +377.21 +183.35 +700.05 +3735.4 +572.4 +1132.6 +730.33 +446.4 +287 +632.54 +393.18 +434.06 +158.4 +191.33 +84.412 +83.693 +939.47 +443.7 +941.02 +199.8 +115.8 +223.6 +465.88 +246.73 +136.06 +261.98 +700.52 +1562.8 +146.32 +127.78 +592.48 +263.74 +190.22 +161.35 +46.306 +56.946 +82.659 +2114 +115.17 +463.11 +0.14831 +245.82 +191.73 +184.58 +371.8 +326.49 +258.87 +63.576 +0.019762 +431.93 +159.85 +475.11 +1040.9 +1296 +841.54 +402.99 +480.07 +51.768 +164.51 +35.035 +215.17 +0.18259 +0.059901 +0.022297 +0.057724 +1241.7 +511.46 +711.68 +609.18 +666.9 +465.13 +290.3 +197.53 +139.85 +73.956 +47.989 +380.39 +311.4 +436.29 +507.97 +186.51 +99.542 +245.37 +266.8 +279.22 +332.02 +665.03 +1611 +1773.7 +4378.1 +74.561 +1272.9 +70.506 +187.63 +112.83 +107.31 +81.716 +1565.5 +187 +0.12202 +0.062345 +136.1 +293.82 +95.402 +315.8 +902.47 +118.94 +150.4 +96.962 +273.84 +1142.5 +801.58 +2156.8 +928.56 +834.15 +251.38 +1995.9 +0.0414 +0.1812 +0.083538 +0.049005 +0.020769 +0.037798 +0.088131 +0.11301 +484 +287.66 +884.71 +751.57 +661.48 +659.77 +887.06 +49.447 +41.445 +43.865 +90.55 +189.94 +189.66 +340.72 +485.29 +172.36 +376.19 +761.83 +5097.5 +1003.5 +652.8 +812.82 +920.85 +1189.6 +4819.4 +6391 +0.16031 +578.67 +96.86 +209.33 +141.24 +79.787 +254.55 +173.46 +0.1296 +0.13914 +0.067583 +305.9 +145.44 +168.87 +1369.7 +2647.2 +307.19 +105.53 +45.156 +1113.6 +707.42 +1885.1 +444.49 +508.44 +338.09 +762.05 +0.052344 +0.21712 +0.19312 +0.067138 +0.079995 +0.20295 +0.45774 +0.22191 +0.078884 +269.33 +1023.1 +1164.5 +1257.6 +660.13 +967.61 +47.455 +73.362 +25.471 +136 +288.71 +177.45 +287.67 +678.17 +280.27 +676.46 +2562.5 +5777.9 +858.92 +1096.5 +1223.6 +1513.9 +1692.3 +5694.7 +2247.1 +3084.9 +2246.8 +155.06 +93.068 +248.55 +57.639 +353.78 +174.1 +244.1 +0.2585 +0.096308 +0.067533 +290.04 +243.93 +1592.3 +3479 +1057 +726.94 +1480.3 +716.51 +357.35 +980.22 +430.01 +382.69 +354.13 +439.31 +0.11339 +0.30329 +0.094161 +0.15305 +0.092782 +0.95161 +0.29201 +0.12462 +1.1793 +116.13 +949.25 +1969.5 +1249.3 +2114.1 +1140.5 +58.849 +118.01 +21.139 +142.71 +196.98 +137.62 +259.94 +1482.5 +238.6 +462.89 +2906.3 +6953.8 +649.48 +178.38 +863.76 +1543.3 +1559.9 +2029.5 +1731.5 +1787.4 +2129 +795.17 +0.32004 +28.991 +50.484 +612.57 +141.55 +122.37 +134.45 +0.041731 +70.702 +51.923 +216.28 +993.01 +2016 +2013.5 +438.78 +1260.8 +746.74 +444.52 +351.23 +325.06 +543.78 +0.16315 +0.28269 +1.9011 +0.20684 +0.11267 +0.13311 +0.29577 +0.21237 +0.14125 +0.20694 +1143.2 +287.82 +1023.5 +1540.8 +1572.5 +1975.2 +1300.3 +46.896 +223.61 +110.88 +119.06 +144.77 +230.61 +362.28 +1128.7 +377.61 +743.6 +850.51 +499.9 +79.682 +81.761 +473.11 +1312.9 +1521.3 +1697.9 +1057.8 +1481.2 +138.08 +234.67 +482.04 +41.854 +70.885 +852.37 +208.12 +102.56 +431.75 +800.76 +149.19 +1667.3 +366.58 +567.42 +1308.7 +2441.6 +427.12 +204.49 +373.9 +393.3 +677.59 +54.114 +105.66 +0.19516 +0.86463 +0.40842 +0.63739 +0.11629 +0.20011 +0.12786 +0.2272 +0.65623 +0.145 +293.95 +435.86 +1092.5 +2019.2 +2179.2 +2114.2 +958.5 +52.593 +257.85 +326.96 +131.97 +129.86 +236.59 +369.02 +633.38 +383 +617.52 +562.76 +264.44 +46.024 +78.95 +426.66 +341.95 +752.15 +2187.7 +1842.8 +1619.1 +0.17471 +0.028696 +0.069955 +0.10603 +66.076 +10.379 +3.3762 +180.07 +171.89 +530.07 +1285.9 +918.53 +609.83 +670.38 +1298.7 +1063.2 +302.36 +235.14 +518 +592.44 +845.55 +0.11983 +71.873 +36.694 +0.38875 +0.19726 +0.43545 +0.04583 +0.077717 +0.12011 +0.10777 +0.211 +0.0708 +402.34 +404.73 +1402 +1299.1 +1455.1 +1231.3 +842.34 +109.15 +852 +392.77 +195.78 +93.879 +420.81 +595.3 +957.1 +134.47 +523.36 +629.52 +369.6 +47.113 +165.11 +450.18 +918.71 +1559.8 +2983.5 +866.86 +0.2149 +0.23093 +0.025442 +0.05904 +0.060502 +0.42906 +5.5339 +2.0516 +25.895 +18.375 +1486 +1062.2 +870.07 +878.63 +523.94 +1583.7 +1303.7 +606.72 +315.82 +263.27 +720.26 +1001.4 +0.32825 +0.19151 +0.04952 +28.273 +25.594 +0.17304 +0.10358 +0.062688 +0.032039 +0.066776 +0.11724 +0.053414 +338.72 +356.68 +670.42 +651.9 +1206.8 +2563.6 +2207.4 +123.79 +1133.4 +227.94 +99.542 +251.43 +420.14 +675.36 +190.71 +142.36 +305.95 +529.74 +381.57 +34.02 +281.94 +408.38 +1053.2 +1533.1 +85.86 +54.615 +0.045374 +0.018717 +0.052816 +0.15296 +0.10399 +0.26042 +2.0728 +10.824 +26.506 +33.959 +26.444 +1596.8 +715.5 +647.18 +437.92 +1536.1 +1037.4 +151.9 +143.99 +0.23796 +0.26085 +440.9 +987.14 +1110.2 +0.04756 +42.925 +31.724 +0.063343 +0.11335 +0.11661 +0.33646 +0.081637 +0.044376 +0.033464 +399.57 +634.47 +378.25 +251.18 +2234 +3176.5 +5028.2 +119.39 +191.37 +432.28 +1214.4 +259.53 +402.38 +399.25 +135.9 +120.39 +288.26 +1529.4 +715.89 +64.168 +235.29 +296.25 +67.732 +89.798 +80.856 +47.942 +84.504 +0.016953 +217.84 +25.735 +116.31 +42.733 +4.3546 +8.2096 +3.1987 +29.043 +87.264 +2195.9 +1737.5 +271.35 +907.2 +90.34 +154.6 +1210 +499.89 +365.24 +0.088524 +0.035878 +738.84 +339.29 +1786.6 +73.325 +41.285 +0.062174 +0.31851 +0.31385 +0.069932 +0.029129 +0.010351 +1044.1 +132.81 +151.32 +199.84 +217.41 +1888.5 +1323.9 +11074 +87.675 +162.49 +616.44 +1663.6 +379.04 +439.35 +378.99 +218.68 +161.71 +383.25 +1563.3 +639.04 +0.10046 +85.418 +114.94 +211 +97.754 +48.24 +55.1 +395.76 +303.97 +87.969 +18.556 +33.902 +9.5661 +2.7022 +4.9639 +10.163 +10.762 +193.61 +240.11 +1197.4 +390.26 +1074.4 +88.767 +0.12781 +964.92 +465.55 +250.53 +188.62 +0.062791 +0.1782 +0.058732 +3739 +108.34 +50.934 +41.785 +0.34159 +0.13706 +0.15684 +0.061521 +895.89 +356.27 +1748.3 +138.95 +107.55 +402.15 +1097.2 +956.96 +2323.6 +108.27 +287.88 +738.59 +1166.4 +486.63 +1031.1 +549.68 +1884.8 +131.24 +1201.6 +539.86 +90.43 +271.83 +40.584 +109.68 +190.63 +40.99 +49.597 +45.415 +333.59 +154.69 +138.68 +44.657 +36.135 +19.532 +4.7297 +7.7976 +8.9658 +5.7267 +56.34 +158.58 +681.4 +501.84 +3357.1 +4292.1 +104.53 +0.1353 +0.051941 +207.97 +375.6 +166.84 +457.15 +0.13671 +0.058822 +149.74 +110.95 +105.9 +114.77 +25.11 +0.05079 +2001.1 +652.04 +560.69 +2134.2 +692.44 +887.08 +217.61 +591.85 +1140.4 +2569.6 +577.13 +498.42 +318.15 +841 +1848.2 +36.32 +574.8 +917.55 +1476.8 +786.21 +265.55 +116.76 +258.44 +59.16 +104.83 +144.92 +69.731 +24.484 +129.36 +159.51 +214.09 +14.247 +32.715 +38.476 +20.739 +8.9799 +7.2342 +16.101 +16.781 +488.44 +538.64 +398.34 +828.09 +106.67 +41.871 +126.78 +0.086474 +0.10149 +0.069468 +1189.7 +189.32 +639.72 +1187.5 +113.05 +132.44 +292.97 +146.56 +64.735 +38.816 +18.292 +21.443 +669.52 +600.39 +123.62 +157.3 +571.08 +1317.9 +523.64 +1525.3 +0.11599 +756.27 +282.38 +699.47 +625.81 +159.69 +53.169 +1012.5 +593.44 +700.98 +433.49 +486.72 +42.075 +151.78 +65.416 +92.607 +102.08 +80.555 +63.733 +130.89 +112.36 +40.615 +16.801 +18.013 +33.207 +17.977 +7.4554 +7.0424 +0.035235 +502.52 +440.23 +178.9 +140.41 +418.76 +178.72 +153.36 +144.63 +0.034636 +0.01696 +0.066269 +37.02 +7.4215 +3.465 +49.714 +384.99 +0.2156 +0.97349 +0.53516 +96.312 +75.404 +50.96 +51.966 +24.959 +465.32 +130.91 +71.074 +89.912 +208.03 +54.671 +25.457 +25.383 +1533.3 +644.72 +280.6 +148.63 +205.22 +1.6084 +0.17917 +470.91 +798.8 +30.033 +116.39 +21.94 +163.12 +188.65 +78.267 +82.16 +87.656 +130.2 +78.487 +64.52 +63.097 +23.338 +41.577 +22.427 +0.26698 +0.07227 +2772.6 +1398.9 +643.92 +225.64 +217.87 +371.62 +340.65 +12.813 +54.096 +103.33 +29.891 +54.058 +57.133 +119.67 +18.702 +273.22 +804.63 +355.27 +255.94 +502.37 +320.26 +310.2 +153.4 +114.34 +24.718 +15.925 +112.02 +217.94 +7.3534 +39.109 +44.272 +22.159 +38.782 +52.373 +30.385 +426.14 +424.47 +718.53 +1029.4 +0.19847 +0.20153 +215.77 +376.5 +44.385 +73.167 +18.186 +297.67 +212.72 +199.79 +166.16 +89.559 +96.9 +153.11 +65.36 +35.015 +32.336 +69.954 +89.352 +143.53 +2648.3 +2124.5 +2055.1 +778.89 +283.17 +221.32 +300.02 +38.698 +15.083 +46.053 +10.561 +71.144 +91.034 +82.09 +0.12253 +0.89744 +0.076039 +477.82 +501.41 +400.27 +441.93 +193.22 +339.72 +257.01 +72.82 +28.552 +43.439 +52.568 +19.558 +46.297 +24.858 +121.14 +17.47 +37.452 +0.072465 +48.038 +581.68 +1130.3 +626.42 +360.05 +0.062185 +197.74 +365.28 +180.19 +68.968 +67.71 +41.945 +277.72 +402.31 +154.34 +143.06 +338.26 +158.11 +62.766 +20.549 +41.364 +33.542 +106.77 +82.653 +200.85 +2148.6 +1275 +1298.1 +265.27 +323.46 +379.42 +0.32796 +47.903 +41.26 +58.991 +31.091 +173.39 +0.1605 +0.12609 +0.17936 +0.64501 +0.17449 +0.074845 +113.57 +260.54 +464.95 +494.73 +31.947 +234.32 +68.536 +63.576 +47.772 +25.674 +18.393 +142.49 +0.024056 +0.097862 +0.073398 +0.21122 +0.41314 +451.36 +1749.5 +589.68 +442.76 +721.83 +3023.2 +220.99 +703.55 +231.9 +106.1 +47.596 +72.048 +107.79 +357.36 +195.69 +185 +37.987 +42.876 +36.504 +134.01 +139.19 +24.233 +109.73 +126.86 +198.37 +759.91 +530.42 +310.9 +180.98 +0.1226 +36.767 +77.535 +64.672 +48.156 +52.085 +31.238 +0.10014 +0.15015 +0.10824 +0.1616 +0.1384 +0.12659 +0.098371 +69.073 +103.85 +276.22 +386.44 +63.309 +24.329 +56.721 +46.97 +26.884 +23.512 +998.77 +34.931 +87.25 +0.067415 +0.86133 +0.076759 +0.18656 +48.34 +27.538 +736.54 +381.83 +246.49 +3545.6 +1.2773 +923.19 +247.82 +293.97 +146.83 +129.83 +71.032 +143.47 +157.1 +70.291 +57.068 +18.112 +256.04 +95.5 +150.79 +19.047 +106.18 +142.36 +627.8 +854.45 +482.76 +0.041095 +482.13 +479.89 +34.668 +32.237 +11.149 +21.67 +36.577 +0.055264 +0.030211 +0.18916 +0.041197 +0.23012 +0.25767 +0.18535 +68.385 +34.255 +114.24 +558.09 +375.53 +67.427 +124.55 +66.604 +131.56 +26.305 +1926.7 +785.01 +0.44827 +0.04744 +59.846 +0.77496 +2.5935 +0.54714 +29.221 +17.378 +5.937 +209.38 +259.79 +868.79 +1739.2 +1014.6 +299.42 +205.64 +153.05 +85.944 +126.24 +188.37 +648.38 +172.7 +138.04 +66.191 +181.49 +95.369 +199.56 +22.052 +47.261 +74.439 +1052.5 +1013.8 +0.021778 +0.03919 +337.48 +1055.3 +50.16 +0.021448 +0.063402 +17.59 +12.243 +0.039517 +0.038394 +0.025718 +0.10192 +0.36288 +0.32193 +0.54223 +30.582 +16.386 +92.145 +304.81 +383.42 +138.95 +179.72 +16.896 +92.312 +860.9 +628.1 +657.3 +290.21 +0.07433 +0.073695 +0.48336 +0.87667 +0.71858 +15.273 +10.698 +8.2003 +12.525 +168.34 +1166.4 +844.42 +586.8 +232.44 +608.06 +115.58 +94.907 +161.09 +231.07 +520.7 +1039 +0.13615 +0.18525 +171.62 +1927.5 +104.85 +39.486 +30.53 +114.67 +594.84 +178.76 +0.071796 +0.11671 +755.1 +1745.4 +186.86 +0.024138 +19.824 +27.499 +18.195 +197.23 +0.30233 +0.083009 +0.5889 +0.79994 +0.21453 +0.28394 +0.090087 +29.891 +24.294 +145.38 +179.98 +147.61 +210.05 +92.321 +41.721 +619.25 +295.13 +556.6 +379.09 +596.95 +0.12375 +0.40087 +0.88514 +0.32101 +13.412 +7.8664 +2.9874 +11.833 +11.58 +18.667 +681.14 +311.61 +316.88 +342.53 +179.22 +157.69 +266.2 +252.09 +525.57 +348.8 +0.070855 +0.11907 +117.89 +1087.3 +1101.7 +49.618 +31.649 +45.615 +221.72 +138.91 +226.83 +1036.4 +875.82 +2119.6 +211.48 +0.018352 +0.028232 +13.519 +36.264 +169.34 +0.066552 +0.13617 +0.6378 +4542.5 +726.64 +30.05 +51.642 +25.493 +30.622 +157.78 +67.765 +139.04 +177.89 +37.449 +44.514 +0.14375 +487.75 +558 +265.24 +443.11 +1384.5 +0.80981 +0.38665 +0.33736 +4.7574 +26.617 +4.7194 +14.607 +14.744 +147.59 +90.592 +456.43 +408.08 +81.184 +67.094 +31.248 +27.379 +281.48 +324.56 +176.9 +0.13061 +71.589 +181.24 +254.15 +573.5 +466.88 +20.069 +55.479 +70.557 +139.58 +127.47 +1490.6 +788.72 +1028 +0.038751 +0.015453 +37.693 +20.275 +32.217 +167.26 +125.91 +4867.5 +8877.5 +4744 +817.33 +35.749 +59.325 +958.25 +195.81 +258.71 +63.075 +156.37 +150.81 +431.78 +1187.2 +0.028357 +375.99 +838.73 +222.5 +394.75 +1870.8 +0.30641 +0.14258 +0.42786 +20.021 +11.69 +5.4684 +19.84 +652.16 +492.08 +174.88 +328.01 +51.1 +97.463 +65.539 +55.23 +7.7214 +14.614 +37.193 +102.32 +2533.2 +585.09 +185.49 +216.1 +651.95 +520.27 +300.72 +58.958 +81.609 +97.312 +75.948 +1433.3 +907.35 +1241.7 +0.05995 +0.070423 +0.44508 +20.826 +59.671 +697.72 +274.65 +346.65 +169.15 +241.8 +290.14 +71.349 +0.47021 +793.28 +224.12 +273.63 +146.82 +148.06 +179.88 +232.27 +613.69 +9.4024 +0.096808 +760.82 +345.81 +430.79 +2224 +459.39 +0.19736 +0.1455 +62.836 +18.177 +204.45 +121.54 +632.85 +862.34 +70.088 +138.22 +129.8 +47.968 +29.455 +66.806 +13.889 +14.37 +43.484 +36.818 +854.44 +1062 +255.67 +201.24 +550.02 +5286.2 +296.44 +155.38 +99.316 +40.106 +169.44 +740.98 +1306.1 +1103.8 +0.25605 +0.35843 +2106 +484.96 +2220.6 +834.45 +330.34 +509.35 +2414.1 +2819.7 +635.36 +0.07977 +0.32448 +520.02 +222.09 +241.45 +226.28 +125.64 +340.08 +299.6 +435.55 +9.7728 +0.1244 +0.05853 +206.18 +827.09 +2866.4 +1257.7 +0.45667 +0.36313 +83.731 +167.17 +190.1 +97.632 +296.33 +335.35 +85.532 +310.68 +219.25 +155.37 +31.289 +61.146 +27.941 +13.055 +46.185 +183.23 +1213.5 +784.46 +318.82 +195.94 +110.56 +3865.2 +3891.2 +85.209 +224.04 +34.712 +115.14 +518.04 +876.01 +1716.3 +428.32 +315.64 +846.44 +372.49 +1481.4 +1189.4 +261.56 +580.89 +3189 +2509.4 +0.10297 +0.046378 +0.074906 +0.31122 +145.46 +334.43 +538.64 +393.19 +74.503 +114.16 +135.53 +5.8721 +11.169 +0.13823 +124.64 +418.85 +1429.5 +710.15 +335.69 +0.52072 +88.318 +59.52 +152.28 +128.36 +459 +248.28 +117.47 +450.69 +0.17389 +288.08 +27.099 +112.61 +40.598 +28.644 +49.515 +394.32 +3566.4 +1099.1 +335.89 +1098.3 +0.011366 +3284.4 +2602.6 +4333 +127.79 +51.8 +264.84 +499.72 +373.39 +557.13 +436.43 +493.29 +660.56 +479.86 +276.32 +203 +210.16 +391.62 +0.20188 +0.070393 +0.049973 +0.08111 +0.073274 +0.095156 +681.82 +942.6 +465.85 +217.13 +103.9 +65.016 +96.499 +13.8 +9.1091 +37.956 +79.985 +234.87 +999.19 +610.2 +454.25 +0.091811 +85.753 +61.127 +121.42 +96.061 +446.39 +237.38 +101.94 +1025.5 +489.33 +242.65 +325.84 +156.06 +40.599 +67.447 +148.68 +1049.7 +2957.5 +1510.6 +630.23 +1094.6 +113.4 +1730.1 +1956.6 +2528 +1088.7 +129.32 +634.36 +369.34 +410.17 +476 +469.77 +14.374 +17.996 +126.14 +289.74 +605.85 +210.27 +391 +0.042449 +0.16027 +0.016946 +0.015409 +0.068875 +43.138 +290.34 +818.35 +641.98 +482.93 +136.26 +77.203 +2.7069 +4.0845 +5.8779 +15.019 +44.188 +414.64 +1083.9 +921.65 +251.23 +0.13003 +90.357 +42.585 +86.969 +64.45 +876.14 +234.04 +56.997 +607.64 +490.28 +44.936 +354.53 +80.268 +27.515 +89.532 +155.06 +906.25 +904.35 +1330.4 +535.8 +1563.8 +3740.5 +1248.5 +2045.5 +1590.2 +2510.2 +52.266 +111.12 +459.63 +683.51 +685.6 +15.426 +12.24 +19.932 +150.57 +189.68 +286.29 +189.83 +0.08544 +0.18577 +0.023424 +0.08264 +0.052771 +55.624 +134.85 +504.88 +1489.3 +827.4 +517.05 +122.22 +8.8171 +1.9658 +2.0627 +7.633 +16.331 +23.068 +960.95 +2077 +774.08 +132.74 +0.36926 +82.21 +110.38 +54.136 +184.39 +196.02 +205.28 +125.46 +452.06 +313.96 +58.049 +14.138 +53.612 +25.246 +81.582 +266.45 +1284.3 +1107.6 +1339.7 +1063.3 +1211 +24.905 +1164.2 +1491.3 +1946.3 +0.085308 +0.019249 +48.907 +759.51 +1457.7 +64.646 +14.602 +18.561 +35.899 +60.252 +611.88 +506.13 +753.37 +0.097946 +0.025892 +0.035392 +0.045721 +0.15179 +172.56 +350.25 +776.41 +765.26 +720.35 +453.6 +16.471 +13.518 +34.595 +0.026014 +10.297 +7.36 +19.813 +39.628 +2455 +1968.5 +172.31 +0.52791 +85.927 +79.914 +106.9 +181.64 +348.37 +271.77 +180.58 +339.07 +240.03 +81.512 +15.008 +58.916 +45.367 +70.907 +126.54 +1357.8 +734.45 +844.5 +1266 +1131.1 +22.526 +0.17569 +539.77 +577.78 +267.14 +310.94 +375.76 +181.61 +875 +74.623 +284.96 +293.64 +2150.2 +803.33 +530.64 +825.42 +470.08 +0.017569 +0.055829 +0.045731 +0.063918 +220.91 +345.71 +335.74 +768 +1187.2 +0.1844 +10.574 +24.056 +11.499 +20.784 +18.517 +0.049389 +7.2861 +9.3063 +31.541 +46.434 +4960 +111.13 +0.28127 +132.79 +88.241 +178.62 +197.21 +640.15 +541.34 +522.28 +294.69 +405.12 +273.26 +38.131 +420.76 +45.479 +91.787 +0.85474 +1272.7 +679.76 +582.39 +567.89 +955.26 +32.407 +889.39 +1324.6 +355.64 +295.44 +221.51 +557.73 +42.52 +72.62 +102.29 +150.01 +133.33 +143.63 +212.3 +370.14 +309.8 +558.49 +0.023853 +0.12282 +0.24652 +172.19 +208.16 +204.22 +383.75 +327.65 +2180.6 +0.32733 +10.5 +8.8149 +20.456 +25.376 +13.497 +150.37 +45.274 +11.425 +18.958 +46.069 +19.463 +0.30165 +0.16494 +129.46 +71.32 +1351.9 +214.33 +1241.8 +455.46 +1405.8 +186.4 +301.11 +422.31 +77.404 +161.28 +235.82 +0.70436 +0.50665 +10294 +578.6 +205.7 +378.31 +247.09 +1722.7 +1064.5 +860.58 +59.366 +125.87 +251.88 +142.26 +50.057 +4358.2 +123.92 +233.85 +317.28 +230.24 +323.35 +237.27 +685.12 +401.23 +466.28 +0.11989 +394.21 +218.89 +144.43 +225.62 +236.91 +0.030465 +0.11116 +0.095551 +0.55263 +9.072 +18.694 +17.052 +13.882 +71.084 +31.57 +128.3 +20.847 +42.064 +17.91 +7.5684 +0.40808 +130.04 +147.14 +590.84 +1294.9 +967.55 +851.26 +475.61 +141.3 +411.69 +802.86 +162.96 +134.36 +230.06 +117.62 +0.36558 +6324.8 +169.88 +296.16 +473.38 +336.53 +1806.5 +2030.7 +173.86 +62.638 +100.26 +440.71 +114.14 +0.40009 +0.30926 +117.54 +110.41 +152.75 +119.06 +193.18 +212.46 +369.12 +0.1836 +508.84 +728.21 +938.31 +292.01 +231.21 +293.95 +304.89 +0.033314 +0.10135 +0.15282 +0.6723 +7.3363 +237.48 +66.958 +12.629 +61.721 +42.823 +253.66 +73.954 +24.763 +18.83 +8.2548 +30.659 +75.263 +970.26 +541.67 +799.48 +1033.2 +581.86 +502.57 +940.34 +420.19 +800.28 +209.65 +101.09 +41.289 +142.82 +62.857 +59.003 +176.32 +115.49 +300.26 +303.52 +3794.6 +87.911 +60.359 +65.53 +112.22 +173.64 +106.76 +34.379 +126.42 +137.34 +91.491 +101.56 +62.362 +173.72 +145.94 +232.28 +9.5405 +0.1921 +0.16813 +664.93 +610.52 +130.54 +192.13 +313.85 +0.15819 +0.1108 +0.052321 +252.69 +93.038 +123.49 +34.536 +19.187 +13.554 +40.676 +133.78 +0.012091 +40.135 +28.928 +20.715 +35.891 +1993.6 +571.15 +581.84 +466.08 +877.04 +470.9 +65.902 +1482.9 +2285.2 +635.27 +305.04 +130.16 +38.112 +97.83 +127.99 +46.226 +96.815 +74.322 +52.556 +149.49 +25.225 +72.068 +72.47 +143.92 +157.84 +0.16203 +37.039 +39.236 +75.323 +232.44 +1630.5 +2434 +121.68 +456.96 +227.48 +130.49 +29.916 +0.58132 +0.067805 +57.089 +239.3 +1148 +136.89 +112.34 +79.663 +0.13417 +0.19175 +0.12631 +260.86 +194.99 +63.405 +9.054 +15.465 +40.581 +0.023232 +0.021142 +0.0293 +21.144 +22.945 +87.37 +1917.5 +915.26 +612.26 +668.67 +735.86 +141.87 +736.14 +560.49 +3120 +354.12 +556.35 +73.302 +59.177 +126.23 +101.26 +32.884 +73.783 +39.784 +42.599 +46.013 +55.69 +63.69 +127.89 +361.11 +44.252 +48.617 +76.659 +47.136 +36.383 +0.086091 +0.13785 +1529.2 +83.681 +918.35 +329.61 +238.79 +34.485 +384.83 +0.40877 +0.11751 +184.83 +853.47 +937.13 +625.27 +30.09 +98.193 +66.893 +0.16512 +712.46 +250.24 +239.78 +16.532 +0.022769 +97.087 +0.082615 +0.030556 +0.039495 +0.076921 +0.03297 +0.13081 +1880.1 +790.72 +571.21 +130.62 +97.113 +83.986 +188.47 +3240.8 +2285.4 +424.58 +533.96 +822.4 +790.61 +190.68 +530.97 +1025.2 +517.29 +57.51 +46.469 +32.37 +68.906 +35.758 +46.614 +37.095 +22.332 +41.674 +128.95 +33.061 +59.754 +0.061617 +0.16163 +0.085615 +61.675 +2246.1 +529.12 +196.44 +70.135 +506.35 +1803.9 +321.68 +842.86 +568.03 +722.48 +340.02 +0.11562 +0.42642 +0.78126 +52.659 +60.41 +115.34 +138.52 +18.54 +0.013211 +0.0147 +0.067439 +0.055727 +0.094388 +0.17427 +0.029811 +0.090882 +2428 +830.66 +617.91 +78.124 +109.96 +48.02 +205.06 +157.11 +116.5 +147.26 +622.43 +677.23 +447.27 +366.81 +599.54 +999.03 +1350.8 +430.52 +54.272 +48.573 +115.9 +84.68 +86.391 +9.7096 +6.48 +30.083 +60.887 +0.055544 +0.11493 +0.29547 +0.10904 +0.046772 +164.55 +848.45 +770.61 +155.78 +219.23 +620.98 +668.22 +1321.1 +659.43 +823.87 +295.02 +227.58 +0.33073 +0.21478 +0.21812 +0.88187 +87.352 +94.317 +79.113 +55.839 +25.99 +0.11826 +0.0463 +0.20368 +0.15934 +0.20266 +0.078118 +0.17133 +1269.2 +694.96 +898.92 +130.92 +98.952 +19.79 +274.99 +67.228 +61.322 +407.21 +242.26 +738.27 +357.11 +250.49 +633.53 +1035.8 +1193.8 +66.531 +119.53 +8.9408 +65.479 +131.95 +109.4 +20.582 +17.322 +19.266 +0.25694 +0.30751 +0.21913 +0.1033 +0.032373 +0.1699 +370.56 +1102.2 +899.91 +310.19 +116.45 +471.68 +2196 +0.2517 +539.89 +367.52 +279.07 +248.3 +120.78 +1.4623 +0.56745 +0.12788 +0.16452 +0.2811 +69.861 +120.9 +24.2 +0.057783 +0.053848 +0.34549 +0.30368 +0.11393 +0.13671 +0.049957 +4577.6 +1355.6 +1169.1 +1865.3 +1300.1 +22.046 +276.4 +38.201 +112.11 +141.8 +121.27 +812.69 +339.75 +340.72 +1749.8 +1232.2 +790.75 +119.01 +35.604 +19.792 +55.792 +91.544 +83.599 +39.487 +14.554 +28.944 +0.095537 +0.34267 +0.12202 +0.072427 +0.092746 +0.10909 +0.055135 +1129.7 +1053 +659.98 +118.1 +280.91 +1990.4 +0.10124 +0.095934 +186.43 +173.01 +231.54 +162.3 +160.33 +170 +0.19699 +0.084227 +0.12183 +50.555 +115.97 +239.76 +202.39 +565.23 +0.050472 +0.13295 +0.15889 +0.00915 +0.064198 +0.16449 +2256.4 +936.02 +795.29 +1198 +346.32 +722.52 +22.909 +74.286 +417.16 +113.5 +453.31 +206.37 +727.65 +1359.7 +2645 +266.94 +111.19 +46.713 +35.39 +33.117 +92.538 +93.318 +40.804 +22.519 +73.753 +202.11 +0.18169 +0.10232 +0.088391 +0.24022 +392.76 +1537.5 +3303.2 +1546.3 +473.38 +327.6 +569.55 +506.92 +181.99 +504.2 +0.20371 +108.06 +205.52 +163.71 +209.54 +235.48 +308.7 +615.5 +0.025609 +0.10415 +15.16 +18.585 +206.75 +614.82 +1118.3 +0.061337 +0.079986 +0.060736 +0.079614 +0.2289 +144.87 +46.092 +68.88 +1366.4 +380.28 +200.68 +315.58 +111.99 +209.48 +163.25 +277.06 +295.44 +219.27 +2084.6 +3052.7 +132.12 +176.53 +92.845 +66.584 +54.093 +46.612 +78.561 +34.317 +146.96 +86.729 +205.64 +55.682 +0.079042 +0.14217 +0.1425 +739.8 +1316.8 +2588 +4526.7 +2313.3 +380.75 +135.57 +379.73 +367.82 +560.19 +970.25 +71.486 +79.599 +97.699 +82.987 +105.01 +882.96 +489.95 +599.38 +698.06 +453.94 +22.206 +75.62 +335.74 +587.02 +282.35 +0.040447 +0.088218 +0.16329 +77.803 +77.391 +119.72 +12.219 +5.9061 +156.03 +278.35 +376.06 +437.36 +190.64 +122.54 +565.25 +682.91 +359.68 +2707.6 +0.072793 +95.906 +114.09 +75.068 +34.858 +60.153 +26.578 +47.649 +282.6 +130.3 +84.802 +140.3 +67.09 +30.589 +0.059206 +742.48 +875.83 +639.03 +1406.1 +4081.3 +929.86 +1336.9 +323.74 +254.24 +241.76 +661.21 +1313.4 +43.589 +42.922 +66.418 +49.554 +134.98 +60.055 +1197.3 +761.6 +986.42 +399.33 +482.13 +162.2 +407.89 +1052.3 +304.01 +0.063463 +0.047209 +0.024671 +63.195 +66.695 +51.83 +53.94 +113.37 +140.95 +114.71 +229.29 +1029.4 +1612.3 +5387.4 +5003.9 +243.19 +9380.7 +923.37 +50.165 +186.82 +277.69 +113.39 +67.843 +59.106 +15.583 +25.626 +20.198 +222.9 +23.408 +83.357 +48.15 +48.912 +0.16764 +656.39 +509.97 +250.51 +527.53 +822.98 +763.49 +1325.4 +441.61 +384.69 +252.12 +0.62489 +0.050631 +41.746 +43.172 +74.317 +60.967 +55.314 +5334.2 +3800 +2996.8 +1119.5 +260.93 +231.5 +307.88 +213.3 +443.96 +392.29 +0.22197 +0.08749 +0.030671 +727.22 +124.38 +84.005 +81.797 +292.63 +247.03 +115.11 +291.74 +881.73 +2682.8 +4328 +5540.3 +5323.4 +86.462 +281.39 +81.598 +179.21 +151.75 +65.767 +112.55 +32.61 +10.206 +19.956 +117.73 +109.03 +57.502 +53.756 +37.745 +80.822 +385.81 +659.12 +674.45 +468.03 +562.78 +1135.6 +460.75 +1074.8 +499.6 +283.92 +395.5 +1236.5 +1638.2 +53.248 +112.71 +69.911 +128.9 +60.747 +4309.6 +2865.6 +2328.2 +624.18 +185.71 +353.75 +239.71 +253.09 +286.23 +0.1082 +0.13238 +0.064563 +0.03965 +334.88 +505.95 +86.81 +178.3 +663.96 +1075.5 +818.29 +577.13 +1774.9 +632.49 +164.9 +5470.9 +8943.5 +3742.9 +1345 +115.24 +144.01 +112.14 +107.65 +89.546 +41.104 +7.1019 +20.637 +43.597 +89.798 +75.311 +74.725 +116.86 +259.26 +455.68 +498.77 +502.82 +704.79 +523.69 +0.41684 +1301.5 +941.47 +1015.1 +251.64 +1433 +1582 +1398.3 +40.127 +198.85 +76.973 +120.06 +7388.2 +3835.5 +251.31 +244.94 +615.07 +301.95 +535.92 +374.12 +0.20206 +0.050042 +0.056924 +0.26609 +0.087839 +0.022109 +368.45 +438.24 +111.09 +132.05 +921.37 +808.9 +1019.5 +531.18 +2149.3 +435.63 +144.87 +230.64 +10643 +5898.3 +2026.1 +40.111 +188.47 +138.91 +168.82 +203.81 +42.116 +5.2948 +22.695 +35.925 +121.14 +612.33 +188.1 +57.532 +293 +570.36 +540.93 +408.08 +579.63 +0.15926 +0.81058 +0.04284 +803.55 +555.01 +437.07 +896.91 +1378.6 +159.61 +68.162 +254.39 +88.432 +14250 +2836.4 +31.255 +285.21 +323.57 +214.99 +90.656 +0.0804 +0.14419 +0.14268 +0.13 +0.053223 +0.15144 +0.29863 +0.035042 +492.88 +210.98 +94.369 +305.37 +662.38 +721.62 +1181.4 +489.78 +438.51 +1218.3 +97.78 +75.163 +4984.5 +4091.3 +60.795 +31.678 +124.76 +198.52 +176.61 +206.67 +37.318 +3.6301 +9.1312 +18.701 +134.01 +231.5 +97.791 +70.328 +279.16 +551.86 +816.88 +349.68 +563.94 +0.85929 +0.42366 +0.18717 +1002.1 +315.58 +666.87 +1031.4 +124.97 +86.975 +97.122 +217.14 +89.2 +872.74 +126.94 +53.245 +546.53 +572.12 +229.6 +0.059899 +0.017263 +0.16697 +0.16621 +0.3571 +0.18074 +0.022769 +0.047176 +0.23812 +434.36 +151.43 +38.136 +218.13 +882.65 +782.61 +1342.9 +1696 +1006.5 +357.73 +634.14 +49.816 +5397.2 +5469.8 +46.838 +33.119 +66.15 +185.11 +105.78 +225.73 +35.267 +14.78 +20.735 +27.536 +24.715 +121.73 +113.63 +55.759 +323.64 +206.89 +763.23 +0.42954 +0.12588 +0.38625 +0.29449 +0.043779 +0.27847 +543.34 +460.2 +1147.8 +238.92 +61.311 +181.05 +208.56 +508.39 +339.02 +175.28 +125 +164.62 +0.043501 +0.02866 +0.062457 +0.040213 +0.11443 +0.21913 +0.11669 +0.04374 +0.016654 +0.17227 +0.062289 +247.2 +218.31 +67.361 +200.25 +612.29 +242.55 +647.37 +2424.1 +1143.5 +952.74 +137.37 +53.519 +7754.5 +79.312 +94.58 +32.569 +77.014 +105.6 +98.382 +187.66 +23.153 +16.673 +23.345 +33.799 +50.45 +64.834 +157.59 +42.568 +261.19 +185.93 +614.25 +0.33103 +0.28102 +0.13799 +0.15294 +0.073055 +0.8494 +127.22 +462.39 +582.03 +179.22 +129.21 +983.13 +763.44 +137.08 +345.52 +88.9 +165.44 +27.223 +0.1583 +0.096839 +0.071621 +0.043791 +0.050473 +0.061135 +0.022685 +0.083898 +0.038899 +0.7427 +0.6071 +267.54 +198.31 +69.754 +84.708 +390.57 +708.21 +2934.1 +1721.4 +1116.8 +1230.7 +174.38 +9386.7 +108.48 +139.66 +75.38 +26.515 +120.66 +108.66 +89.76 +344.93 +74.355 +68.365 +34.298 +28.465 +48.124 +70.851 +96.992 +61.976 +371.84 +1575.1 +1094.2 +342.1 +0.077362 +0.076971 +0.05553 +0.12666 +295.68 +252.99 +382.44 +483.03 +458.97 +85.039 +498.06 +810.13 +103.07 +208.19 +161.99 +125.81 +0.1919 +0.12191 +0.037021 +0.29284 +0.052602 +0.32042 +0.046684 +0.1262 +0.44467 +0.64395 +0.06337 +0.2208 +223.39 +273.76 +67.621 +70.992 +506.43 +851.67 +2396.2 +1877.6 +62.199 +28.433 +732.63 +765.14 +220.15 +235.48 +61.016 +26.896 +87.236 +70.419 +203.86 +357.74 +58.619 +70.907 +334.52 +60.353 +98.742 +99.331 +142.46 +37.093 +187.75 +1227.5 +1563.1 +300.69 +0.064358 +0.18656 +81.927 +46.866 +250.13 +291.85 +794.61 +735.84 +667.5 +206.08 +413.8 +139.57 +101.27 +34.505 +106.77 +0.10019 +0.11337 +0.081098 +0.13903 +0.17152 +0.057469 +0.27896 +0.089418 +0.73589 +0.32431 +0.64672 +0.34203 +0.065661 +160.32 +80.67 +123.31 +179.51 +350.25 +5073 +3533.3 +115.99 +157.95 +8106.2 +1879.3 +648.6 +84.411 +303.74 +100.71 +38.849 +86.472 +161.51 +263.09 +195.46 +89.781 +39.924 +225.73 +42.995 +78.674 +53.808 +94.261 +88.364 +373.94 +996.86 +1341.8 +464.36 +0.039879 +65.058 +91.046 +81.726 +381.79 +1495.5 +683.13 +1123.8 +517.43 +163.17 +24.442 +40.156 +38.388 +25.15 +94.066 +0.024743 +0.068258 +0.19848 +0.93696 +1.4281 +0.11725 +0.15148 +0.1642 +0.23464 +0.22145 +0.19224 +2.505 +0.70668 +201.05 +90.126 +126.88 +1190 +777.07 +4899.7 +678.77 +1130.2 +6.7953 +10596 +3770.2 +779.21 +176.74 +157.91 +168.41 +66.738 +76.78 +96.715 +182.56 +18.197 +54.624 +44.979 +83.368 +60.242 +73.634 +65.679 +70.81 +537.25 +451.41 +719.55 +1099.7 +340.66 +322.84 +40.488 +616.53 +3816.4 +1162.9 +1224.5 +416.71 +1044.3 +9063.2 +70.761 +17.786 +76.351 +27.221 +10.547 +16.9 +0.021039 +0.045338 +0.095938 +0.13353 +0.31105 +0.055649 +0.083421 +0.044455 +0.016204 +0.14049 +0.34422 +0.09559 +0.34635 +140.15 +1944.3 +836.85 +359.34 +380.13 +902.41 +896.1 +916.53 +260.12 +5520.8 +1990 +487.75 +384.89 +111.42 +189.71 +50.02 +137.73 +165.61 +67.841 +17.14 +69.179 +42.488 +52.427 +84.819 +103.17 +44.679 +83.167 +342.59 +1181.8 +378.38 +1105.3 +410.63 +8129.5 +2901.9 +627.33 +1594.8 +725.26 +1002.6 +0.09602 +0.063524 +6443.4 +103.58 +26.237 +86.196 +51.087 +25.939 +31.543 +0.014291 +0.004506 +0.030525 +0.15593 +0.18315 +0.043413 +0.24672 +0.046868 +0.14889 +0.18599 +1.9303 +0.37693 +0.41698 +630.52 +944.82 +97.564 +296.6 +185.71 +986.83 +1218 +1653.2 +469.28 +3312.5 +1509.8 +443.92 +330.44 +123.85 +136.11 +39.228 +159.79 +0.73861 +30.21 +40.968 +27.758 +59.848 +46.37 +1098.8 +43.889 +98.104 +40.548 +235.48 +669.96 +348.12 +370.51 +243.04 +4807.6 +3606.9 +576.44 +1256.6 +0.30355 +0.17953 +0.29701 +0.053853 +5896.5 +50.044 +46.258 +47.816 +42.806 +69.952 +106.56 +0.34318 +0.025863 +0.1704 +0.13901 +0.095444 +0.092367 +0.12837 +0.018696 +0.016011 +0.044065 +0.1034 +0.068349 +0.1808 +619.98 +312.02 +129.54 +279.42 +216.25 +123.29 +983.97 +3944.9 +543.57 +3465.9 +1794.2 +315.24 +364.92 +128.76 +316.27 +40.732 +118.16 +1.2723 +46.693 +17.538 +73.975 +108.89 +99.22 +125.81 +113.48 +227.24 +75.975 +202.5 +902.64 +434.51 +241.82 +7366.6 +5050.8 +5326 +98.017 +69.843 +0.16565 +0.25871 +0.077979 +0.077727 +202.77 +44.166 +74.829 +52.991 +37.051 +79.419 +245.29 +188.46 +0.022691 +0.013789 +0.14137 +0.053556 +0.10356 +0.11882 +0.10259 +0.019621 +0.043758 +0.20601 +0.11421 +0.42741 +1109.6 +2030.4 +2451.1 +313.58 +596.71 +125.66 +135.84 +442.03 +778.45 +810.21 +738.1 +315.35 +382.64 +106.18 +173.69 +84.679 +92.843 +17.735 +65.789 +39.076 +56.094 +163.55 +164.85 +495.57 +125.21 +269.44 +118.81 +242.01 +929.05 +716.76 +4381 +4876.5 +4573 +148.31 +96.322 +59.475 +0.042397 +0.076226 +0.13975 +456.51 +118.43 +34.431 +67.079 +45.391 +34.866 +59.594 +104.74 +147.49 +0.10363 +0.056511 +0.14809 +0.098921 +0.031666 +0.025205 +0.11921 +0.045407 +0.094984 +0.23079 +0.096631 +0.10193 +1.6416 +4695.7 +294.95 +3856.5 +302.47 +31.979 +65.641 +462.15 +704.75 +917.91 +575.57 +175.31 +231.62 +176.22 +98.136 +80.741 +111.14 +19.508 +34.909 +14.136 +30.208 +186.59 +73.34 +291.55 +276.49 +240.13 +418.12 +234.08 +607.79 +2757.4 +4920 +2799.4 +4729.3 +2626.9 +128.68 +46.913 +0.0726 +0.072401 +841.44 +646.64 +224.38 +45.655 +60.483 +67.441 +355.93 +571.9 +179.15 +58.79 +197.9 +0.13627 +0.30573 +0.11765 +0.067013 +0.018219 +0.016733 +0.057497 +0.064122 +0.13514 +0.090312 +0.066371 +4.7209 +2.5143 +943.4 +322.96 +0.23517 +30.915 +100.11 +376.11 +337.24 +723 +1056.2 +761.33 +176.87 +55.933 +104.28 +81.898 +96.379 +71.783 +21.72 +10.677 +22.403 +153.35 +63.851 +97.804 +165.95 +296.34 +496.23 +184.7 +412.73 +43.664 +5602.1 +4002.9 +1860.3 +2679.2 +59.8 +50.525 +38.697 +775.63 +572.89 +1475.9 +336.99 +115.05 +649.9 +2193 +245.61 +744.1 +191.27 +84.952 +170.41 +0.026531 +0.1137 +0.027563 +0.028579 +0.017583 +0.017441 +0.005683 +0.024632 +0.040253 +0.13334 +0.18874 +4.8316 +5.5234 +535.21 +98.258 +998.54 +653.23 +20.796 +9.0748 +360.11 +1302.8 +1828.5 +1244 +933.62 +55.069 +69.321 +40.333 +36.342 +121.36 +10.116 +15.08 +36.442 +168.15 +122.2 +124.15 +278.44 +425.85 +468.23 +154.97 +126.34 +23.184 +50.346 +3712.7 +1466 +1793.8 +1386.8 +72.252 +51.122 +178.73 +551.67 +1585.6 +331.67 +348.35 +353.49 +1277.2 +635.25 +392.83 +91.123 +96.079 +227.47 +0.006421 +0.049285 +0.044429 +0.008224 +0.047792 +0.068893 +0.017327 +0.039469 +0.08043 +0.13022 +0.082486 +5.1338 +4.1562 +16.882 +141.76 +734.8 +2930.1 +323.75 +0.52506 +21.982 +1693.4 +1727.6 +1895.2 +957.11 +1074.9 +70.258 +52.68 +45.589 +210.09 +42.13 +10.354 +19.661 +79.071 +222.31 +67.117 +218.7 +193.49 +238.43 +296.85 +85.012 +40.904 +59.337 +3410.2 +1700.5 +1296.7 +2115.4 +2930.4 +20.937 +123.49 +62.511 +141.19 +327.3 +221.18 +240.25 +612.72 +330.89 +233.97 +80.032 +61.025 +116.47 +281.4 +0.35713 +0.029346 +0.027064 +0.035857 +0.045525 +0.006328 +0.048262 +0.072376 +0.089183 +0.25604 +3.9534 +6 +84.076 +112.48 +471.24 +1950 +230.46 +226.41 +233.52 +152.13 +1310.9 +1663.7 +779.52 +758.12 +405.68 +66.272 +65.105 +85.09 +58.834 +60.204 +18.779 +234.33 +104.95 +30.056 +12.884 +330.23 +366.01 +526.89 +130.22 +41.978 +39.877 +83.094 +672.33 +1758.8 +1338.8 +2849.5 +73.871 +95.442 +131.27 +78.909 +294.33 +273.98 +396.63 +483.5 +493.7 +244.6 +137.36 +84.581 +165.83 +181.96 +0.24078 +0.047571 +0.042202 +0.11999 +0.03037 +0.009228 +0.021816 +0.030977 +0.17975 +0.24829 +7.4315 +7.293 +52.933 +6.5971 +293.88 +4863.8 +928.3 +112.59 +183.04 +21.641 +15.022 +717.13 +1614.8 +629.28 +542.28 +142.76 +73.015 +66.367 +18.333 +61.114 +41.806 +59.816 +43.447 +37.07 +16.375 +455.18 +601.62 +1983.8 +127.05 +63.564 +9.1131 +81.932 +65.859 +145.19 +665.97 +3082.9 +4975.3 +277.61 +181.54 +86.337 +81.146 +293.29 +327.72 +1073.8 +512.55 +347.1 +134.98 +157.76 +265.3 +0.054571 +0.18742 +0.082125 +0.033194 +0.081653 +0.049311 +0.058793 +0.020303 +0.067323 +0.13689 +0.20344 +13.834 +9.772 +48.885 +12.516 +16.256 +4965.6 +1659.5 +141.05 +193.06 +35.968 +34.877 +52.472 +1344.1 +493.89 +612.7 +188.02 +52.916 +39.841 +20.352 +33.753 +15.054 +41.654 +106.28 +51.689 +14.346 +536.01 +672.32 +1050.8 +98.978 +107.55 +15.315 +67.565 +25.825 +90.562 +551.62 +3907.9 +2211.4 +297.49 +141.52 +74.294 +84.463 +497.94 +321.86 +798.51 +997.35 +245.92 +207.91 +289.35 +0.067189 +0.12025 +0.11858 +0.3864 +0.10523 +0.3428 +0.18746 +0.034576 +0.089765 +0.059297 +0.10473 +0.15225 +13.86 +12.321 +31.326 +8.9195 +323.04 +134.71 +145.97 +451.24 +59.115 +55.685 +85.474 +88.555 +15.423 +555.67 +479.14 +128.05 +150.63 +41.16 +23.577 +29.607 +19.572 +39.653 +43.109 +160.17 +80.801 +224.67 +1174.8 +861.35 +152.29 +315.12 +194.56 +111.59 +30.172 +65.475 +134.45 +87.755 +1186.3 +223.71 +353.59 +128.69 +151.5 +268.89 +968.96 +1414 +744.6 +320.58 +282.53 +249.62 +0.24849 +0.29093 +0.25982 +0.99116 +0.3283 +0.11002 +0.048244 +0.043303 +0.072392 +0.17545 +0.15748 +0.36863 +23.905 +11.748 +21.218 +14.339 +882.83 +0.18589 +229.16 +67.704 +51.019 +60.503 +77.169 +186.56 +51.586 +226.58 +404.33 +171.54 +152.9 +60.561 +24.917 +57.242 +9.1754 +32.435 +40.515 +80.929 +348.09 +111.32 +215.36 +47.265 +134.04 +321.31 +58.288 +80.063 +73.861 +51.005 +122.88 +61.66 +84.99 +103.96 +163.11 +97.962 +366.93 +65.736 +1681.3 +891.47 +1001.1 +361.26 +0.066279 +1.296 +0.32493 +0.25601 +0.095479 +0.46714 +0.24702 +0.89324 +0.098013 +0.035136 +0.018783 +0.17505 +0.072354 +0.055295 +33.351 +16.96 +8.6701 +8.6353 +1357.9 +17071 +40.055 +73.379 +11.504 +60.006 +75.506 +97.137 +81.796 +176.72 +449.69 +284.16 +284.44 +64.221 +22.822 +42.988 +6.3771 +31.072 +155.39 +84.027 +343.38 +102.21 +129.57 +151.28 +89.326 +0.3188 +71.084 +105.42 +165.84 +125.81 +80.866 +98.395 +400.75 +125.72 +136.44 +81.719 +165.66 +63.942 +32.455 +527.23 +0.2479 +0.61274 +0.17505 +0.083339 +0.040549 +0.11917 +0.023824 +0.012139 +0.084957 +0.17797 +0.031481 +0.033224 +0.097474 +0.072072 +0.25574 +0.021377 +81.456 +41.589 +17.169 +15.404 +18.925 +137.16 +71.361 +64.516 +24.209 +43.195 +48.634 +196.69 +93.569 +225.12 +269.47 +95.372 +97.168 +79.84 +43.41 +64.213 +22.325 +161.14 +161.91 +112.26 +381.76 +61.769 +42.907 +56.459 +53.078 +28.73 +21.702 +67.963 +330.26 +135.12 +75.358 +329.75 +213.26 +188.26 +198.99 +64.303 +75.372 +47.043 +56.7 +0.032864 +0.29714 +1.2298 +0.13757 +0.43475 +0.17595 +0.20137 +0.32128 +0.013389 +0.067862 +0.076756 +0.0317 +0.008228 +0.026471 +0.065689 +0.084098 +0.020856 +108.99 +86.414 +21.645 +10.701 +114.78 +275.89 +59.646 +39.61 +30.829 +74.772 +1519 +233.41 +523.44 +182.64 +333.42 +103.08 +112.67 +156.47 +93.292 +161.39 +46.35 +53.415 +141.95 +93.537 +384.86 +79.639 +28.888 +48.559 +25.837 +23.973 +30.127 +25.532 +187.03 +189.41 +289.04 +406.55 +210.14 +606.31 +187.78 +47.317 +82.751 +0.23591 +0.1827 +0.036279 +0.14376 +0.18934 +0.13446 +0.16527 +0.4125 +0.46207 +0.34286 +0.021036 +0.032588 +0.12984 +0.038536 +0.014503 +0.013669 +0.071847 +0.14763 +0.14067 +90.213 +65.786 +15.323 +7.8638 +65.005 +306.02 +47.255 +681.07 +1381.9 +351.98 +609.14 +100.44 +312.94 +193.92 +265.78 +138.72 +154.29 +101.86 +70.404 +457.99 +81.21 +172.72 +137.15 +127.15 +260.87 +49.476 +44.337 +79.109 +98.754 +24.538 +17.166 +293.03 +160.9 +458.07 +274.75 +165.74 +188.53 +320.87 +140.04 +51.183 +1.2868 +0.49845 +0.069229 +0.068235 +0.023328 +0.14641 +0.55429 +0.32456 +0.11474 +0.18441 +0.037657 +0.033751 +0.046685 +0.052535 +0.43469 +0.091557 +0.053914 +0.12411 +0.26058 +0.044777 +57.603 +39.499 +18.982 +23.733 +427.31 +876.15 +463.67 +1407.7 +853.21 +730.83 +330.03 +72.821 +112.34 +173.86 +193.12 +8.4912 +8.216 +11.125 +183.18 +505.43 +13.04 +75.922 +145.12 +70.374 +165.03 +85.525 +0.03948 +0.063966 +51.063 +33.086 +16.826 +817.65 +290.85 +646.82 +213.6 +303.6 +161.68 +255.62 +0.6356 +0.17687 +0.94067 +0.55357 +0.16547 +0.062933 +0.061666 +0.011768 +0.049334 +0.10235 +0.032313 +0.18103 +0.056532 +0.17429 +0.091581 +0.16587 +0.11756 +1.0874 +0.31652 +0.22127 +0.070532 +0.033851 +57.026 +23.962 +1257.1 +1294.5 +626.19 +498.79 +287.61 +1541.1 +794.01 +508.54 +268.58 +147.68 +230.31 +75.688 +49.627 +6.2095 +217.31 +1197.9 +321.83 +191.44 +14.379 +79.972 +97.126 +136.82 +0.021514 +0.007827 +20.047 +0.053468 +41.131 +51.024 +1131.7 +902.49 +339.53 +1130.6 +302.85 +378.92 +145.17 +0.057038 +0.19252 +0.48657 +0.90054 +0.38425 +0.38058 +0.12796 +0.16751 +0.031015 +0.063999 +0.082118 +0.1279 +0.01472 +0.22981 +0.40355 +0.62896 +0.10493 +0.22375 +0.41069 +0.15286 +0.053713 +0.43361 +0.060175 +104.99 +14.189 +1179.7 +1157.6 +622.49 +753.82 +221.04 +1166.6 +955.65 +193.41 +287.64 +994.52 +114.24 +87.471 +35.783 +186.41 +359.33 +511.98 +160.38 +104.18 +32.682 +117.91 +270.65 +0.03439 +0.00761 +0.036021 +0.054414 +0.055327 +1908.1 +733.07 +902.34 +1231.9 +862.63 +832.6 +193.6 +281.07 +216.62 +0.055577 +0.055177 +0.1469 +0.11132 +0.62654 +0.35621 +0.084066 +0.12204 +0.54041 +0.026394 +0.063307 +0.01806 +0.069225 +0.21656 +0.38735 +0.16511 +0.044637 +0.14374 +0.44954 +0.40793 +0.022452 +0.022494 +0.017912 +204.88 +192.87 +219.84 +1139.2 +799.04 +585.47 +169.12 +944.73 +1292 +648 +2201.8 +532.67 +157.91 +60.103 +765.2 +288.78 +37.104 +41.414 +214.75 +68.606 +36.105 +1728.9 +0.087427 +0.091913 +0.14966 +0.24793 +0.097395 +0.15154 +1643.4 +1339 +507.75 +988.36 +14.16 +6.465 +67.495 +278.63 +608.36 +20000 +0.29726 +0.081376 +0.13631 +0.15145 +0.24469 +0.078288 +0.21849 +0.25451 +0.10246 +0.042455 +0.009998 +0.43855 +0.1858 +0.23549 +0.28397 +0.034734 +0.56939 +0.065779 +0.2423 +0.022365 +0.037905 +0.064475 +152.41 +183.65 +179.18 +484.45 +976.5 +598.33 +368.57 +687.21 +2370.9 +358.39 +1192.2 +397.32 +240.24 +136.75 +114.15 +27.8 +50.863 +42.337 +302.4 +381.22 +292.89 +3380.7 +0.4495 +0.37642 +0.47346 +0.40705 +38.559 +24.115 +7.0979 +20.524 +8.2543 +579.13 +441 +7.0297 +463.65 +149.05 +914.35 +11424 +5306.7 +0.065776 +0.083743 +0.17129 +0.12881 +0.098865 +0.099205 +0.36675 +0.076694 +0.050893 +0.10022 +0.22813 +0.19426 +0.054389 +0.052722 +0.052901 +0.15553 +0.10725 +0.16306 +0.36958 +0.23806 +0.23328 +128.38 +271.95 +268.3 +460.67 +926.67 +609.86 +576.22 +777.15 +2205.7 +845.24 +186.52 +343.57 +70.418 +87.967 +64.561 +16.164 +30.278 +3450.5 +254.44 +515.36 +466.31 +1601.7 +0.062995 +198.11 +63.856 +8.2241 +28.476 +37.953 +67.873 +38.098 +15.502 +14.066 +390.38 +9.3938 +14.959 +264.15 +330.88 +4883.9 +6483.2 +0.027342 +0.080711 +0.26539 +0.14223 +0.036764 +0.068373 +0.086826 +0.061436 +0.09274 +0.11073 +0.034654 +0.053774 +0.058785 +0.04813 +0.068237 +0.045184 +0.05324 +0.15088 +0.45824 +0.064929 +0.56958 +153.19 +474.61 +285.46 +548.46 +429.69 +752.81 +222.22 +1052.4 +1125.2 +1019.4 +301.31 +318.53 +40.414 +61.805 +47.064 +19.572 +2912 +2965.7 +1285 +1100 +368.53 +1106.3 +1524.8 +3244.8 +18.927 +11.331 +11.707 +40.729 +108.74 +25.58 +35.538 +15.585 +403.6 +79.298 +10.801 +26.854 +1.0501 +2549.3 +9614.1 +1000.4 +0.014624 +0.12442 +0.046415 +0.11215 +0.061612 +0.045251 +0.003685 +0.050648 +0.08627 +0.27103 +0.12599 +0.033378 +0.14017 +0.069181 +0.03481 +0.072204 +0.032787 +0.28272 +0.34053 +1.5226 +204.37 +3370 +959.85 +695.88 +580.35 +361.46 +701.47 +240.6 +353.84 +84.332 +196.92 +434.97 +23.003 +33.641 +27.741 +17.255 +5490.5 +5361.9 +5047.3 +1393.5 +957.77 +2251 +2576.6 +8013.5 +18.239 +16.713 +23.37 +35.998 +93.786 +47.002 +45.523 +449.01 +501.89 +17.411 +13.378 +23.224 +8.6063 +0.36344 +7010.9 +768 +1165.5 +0.20792 +0.14701 +0.096241 +0.22517 +0.070283 +0.016705 +0.040251 +0.017631 +0.13341 +0.049896 +0.25569 +0.23034 +0.12899 +0.064062 +0.034764 +0.028653 +0.25073 +0.31567 +1.0596 +345.68 +592.28 +2134.2 +1202.9 +539.47 +330.7 +409.63 +1199.2 +668.86 +124.53 +101.03 +15.569 +146.77 +32.936 +52.947 +13.684 +38.817 +5523.1 +5910.9 +558.18 +781.59 +5226 +5629.1 +7637.8 +7.106 +13.787 +34.437 +19.076 +35.607 +43.835 +56.498 +306.37 +372.91 +41.495 +21.882 +11.719 +9.6909 +0.40136 +0.1059 +841.57 +938.07 +487.94 +0.010238 +0.10553 +0.046506 +0.11898 +0.062395 +0.074887 +0.037402 +0.041439 +0.085629 +0.12357 +0.48259 +0.05641 +0.02809 +0.008891 +0.078475 +0.35253 +0.59843 +0.30841 +146.21 +95.998 +674.8 +1106.9 +441.7 +156.68 +447.74 +203.49 +320.22 +42.279 +114.12 +17.376 +116.68 +25.078 +60.922 +36.217 +45.414 +88.563 +6366.7 +491.95 +1182.1 +6178.2 +4796.2 +4481.3 +0.20407 +11.856 +21.926 +16.243 +23.729 +0.093971 +61.36 +361.93 +277.8 +46.069 +13.812 +16.442 +18.608 +4.5053 +0.034962 +0.063652 +1385.7 +386.44 +246.84 +0.14137 +0.45911 +0.34995 +0.26907 +0.36218 +0.19126 +0.1741 +0.022072 +0.16994 +0.038305 +0.050812 +0.069623 +0.006206 +0.021296 +0.292 +0.34715 +1.0713 +112.36 +43.416 +190.52 +686.82 +413.38 +220.37 +834.74 +748.82 +253.5 +57.745 +150.11 +21.212 +125.76 +36.243 +80.544 +84.903 +47.81 +51.836 +4049.5 +490.62 +194.32 +170.38 +5763.9 +4597.6 +0.90267 +0.86948 +0.81293 +0.25663 +0.2 +0.26418 +79.064 +141.85 +153.54 +35.027 +9.3936 +9.1993 +7.5821 +5.5996 +20.028 +0.044108 +0.11056 +240.89 +200.69 +123 +3.858 +3.0067 +0.40047 +0.25624 +0.61325 +0.57434 +0.35709 +0.11586 +0.034646 +0.02964 +0.068849 +0.014857 +0.005365 +0.35297 +0.50582 +1.1016 +113.23 +42.231 +111.29 +474.44 +468.83 +138.11 +277.49 +864.62 +201.23 +42.901 +62.746 +12.645 +115.77 +56.018 +53.807 +98.567 +70.706 +51.033 +24.592 +24.543 +210.43 +311.09 +80.96 +1853.7 +1440.3 +0.54587 +0.83071 +0.06988 +0.051265 +0.082991 +112.97 +320.2 +941.72 +2241.3 +19.074 +6.5456 +4.8211 +14.334 +6.48 +0.065746 +0.1132 +161.3 +61.142 +35.962 +13.512 +0.32989 +0.2049 +0.17805 +0.56547 +0.4957 +0.37138 +0.053374 +0.063802 +0.2806 +0.061452 +0.33847 +0.034291 +0.23814 +0.39771 +0.21901 +202.85 +43.508 +169.32 +52.427 +532.14 +1187.8 +233.47 +1208.8 +1634.6 +27.691 +38.937 +14.39 +7.947 +108.84 +68 +180.3 +106.66 +98.757 +25.396 +26.562 +52.594 +446.93 +75.141 +1957.7 +1161.5 +0.23214 +0.07412 +0.024165 +0.26018 +534.5 +116.63 +253.85 +190.13 +1612.9 +2283.9 +4.503 +4.6024 +10.57 +7.8631 +0.036369 +0.096908 +170.91 +53.093 +24.879 +27.583 +0.9919 +0.32218 +0.13575 +0.76685 +0.55023 +0.15789 +0.1557 +0.19741 +0.27046 +0.17342 +0.32438 +0.41117 +0.53851 +0.18219 +0.12775 +258.79 +76.91 +70.134 +83.549 +435.83 +103.45 +227.57 +1113.3 +1388 +655.59 +2554.8 +8.1038 +84.266 +232.55 +67.19 +153.73 +125.53 +431.86 +421.9 +23.984 +82.514 +49.544 +64.313 +83.672 +0.14088 +0.18529 +0.31038 +0.10529 +0.046473 +105.35 +76.261 +176.49 +137.31 +906.64 +1079.8 +287.75 +5.4632 +8.6178 +8.0025 +0.057809 +0.26716 +185.3 +35.779 +29.912 +51.068 +3.3967 +0.2249 +0.13473 +0.48103 +2.0001 +0.40828 +0.50174 +0.20536 +1.2002 +0.54592 +0.073546 +0.13058 +0.087965 +0.17538 +0.051666 +11951 +571.83 +65.441 +83.139 +100.29 +254.07 +481.44 +423.91 +313.72 +1852.2 +1201.8 +2723 +149.5 +281.99 +109.16 +119.64 +178.39 +32.871 +133.76 +202.18 +142.37 +91.291 +49.243 +67.492 +0.23922 +0.072452 +0.059104 +53.378 +81.514 +62.733 +69.171 +178.6 +78.902 +881.99 +789.59 +229.26 +345.68 +0.33845 +0.169 +0.65015 +653.95 +115.03 +40.762 +28.143 +18.116 +0.056281 +0.074211 +0.063786 +0.22665 +1.1135 +1.8627 +1.0306 +0.46698 +0.32024 +0.36744 +0.30865 +0.68378 +0.054778 +0.022752 +0.098575 +695.26 +314.55 +48.36 +116.48 +120.29 +758.04 +492.65 +387.25 +802.26 +364.69 +362.89 +2585 +1731.8 +813.71 +164.31 +118.89 +270.48 +47.187 +138.89 +257.83 +334.57 +185.02 +35.568 +65.29 +91.223 +74.021 +58.67 +89.157 +42.217 +144.56 +116.89 +382.92 +178.73 +1253.8 +413.14 +328.28 +191.12 +124.56 +66.652 +221.72 +485.79 +142.67 +22.968 +50.586 +0.065482 +0.096258 +0.07727 +0.45136 +0.7232 +0.50779 +0.35879 +1.3405 +0.9348 +0.25919 +0.31328 +0.30467 +0.11207 +0.078028 +0.092702 +0.044516 +3911.3 +117.63 +47.884 +44.938 +153.72 +631.03 +409.18 +363.28 +406.72 +1529.7 +1943.4 +752.7 +2317.6 +1037.6 +205.51 +175.65 +215.92 +410.92 +136.63 +40.846 +10.936 +0.035188 +0.037047 +94.905 +79.32 +76.547 +28.58 +97.661 +90.744 +341.78 +915.11 +463.13 +203.47 +1214.2 +187.42 +93.426 +102.97 +247.47 +122.24 +379.72 +949.23 +184.88 +34.48 +0.14067 +0.16036 +0.32147 +0.55511 +1.6732 +1.485 +0.30166 +0.35656 +0.87711 +1.5999 +1.2133 +0.071639 +0.097078 +0.062833 +0.078319 +0.11189 +0.052087 +75.47 +327.33 +810.94 +48.94 +112.36 +135.99 +564.03 +428.81 +325.42 +943.08 +1018.4 +446.23 +115.62 +1086.5 +84.748 +333.55 +335.2 +170.43 +90.889 +30.856 +18.218 +0.08446 +289.18 +35.908 +116.06 +150.16 +50.736 +87.845 +84.283 +686.2 +1359.7 +1156.3 +5158.4 +0.03407 +0.012671 +33.992 +0.16328 +0.23849 +0.10527 +0.19088 +0.14316 +0.049323 +0.25146 +0.13173 +0.05233 +0.29288 +3.2381 +1.7772 +1.2188 +0.30211 +0.45187 +0.81733 +0.95902 +0.82853 +0.13628 +0.24409 +0.073842 +0.071618 +0.091826 +0.007311 +56.215 +191.47 +864.48 +130.37 +81.244 +94.073 +450.03 +246.6 +80.84 +431.87 +546.67 +590.07 +120.21 +112.54 +123.52 +283.8 +398.25 +75.39 +81.79 +55.74 +0.080217 +0.18078 +72.451 +16.982 +90.54 +162.77 +33.063 +488.43 +174.03 +1234.7 +1039.1 +42.749 +274.46 +0.019462 +0.12007 +0.19701 +0.27779 +0.19921 +0.31658 +0.19006 +0.20798 +0.14864 +0.30309 +0.18967 +0.12345 +0.19997 +0.16787 +0.24989 +0.099583 +0.51502 +0.28993 +0.28413 +0.60542 +0.1241 +0.11731 +0.16837 +0.093039 +0.056192 +0.078605 +0.18962 +55.558 +30.342 +1549.3 +189.7 +89.231 +140.53 +480.34 +598.94 +109.5 +266.7 +378.21 +548.59 +412.09 +145.58 +94.823 +363.46 +287.54 +64.579 +48.83 +79.264 +54.063 +29.332 +41.572 +14.703 +134.29 +177.88 +41.869 +419.71 +197.37 +385.14 +1603.4 +16.175 +0.23558 +0.047942 +0.057576 +0.54416 +0.48425 +0.30715 +0.70684 +0.27651 +0.29715 +0.20019 +0.1284 +0.43112 +0.1543 +0.10444 +0.086 +0.78884 +0.31419 +0.38494 +0.57546 +5.5527 +0.67306 +0.28949 +0.032038 +0.25226 +0.12284 +0.093856 +0.12448 +0.37224 +132.87 +61.206 +1156.4 +232.62 +124.87 +109.49 +347.17 +358.27 +209.4 +177.35 +436.02 +421.17 +378.35 +402.46 +346.72 +180.53 +83.654 +64.524 +78.777 +229.11 +72.587 +29.299 +38.82 +179.89 +221.37 +407.22 +3216.7 +3847.9 +73.903 +30.069 +69.121 +20.66 +0.31024 +2.3437 +0.28557 +0.2806 +0.52248 +0.55234 +1.6657 +0.10042 +0.20653 +0.44536 +0.2626 +0.12362 +0.021098 +0.009823 +0.066443 +0.15849 +0.035409 +0.020897 +0.38456 +1.5403 +1.7864 +0.92947 +0.1211 +0.18169 +0.03437 +0.068512 +0.0726 +0.063071 +127.7 +102.22 +41.982 +143.75 +132.75 +75.615 +202.33 +306.12 +238.7 +208.67 +423.31 +827.72 +818.41 +633.15 +892.4 +165.11 +94.909 +106.2 +179.32 +471.13 +53.886 +104.46 +30.052 +303.97 +175.25 +384.58 +83.087 +3380.1 +62.574 +46.787 +130.47 +1.6314 +1.4338 +0.68098 +0.23397 +0.28988 +0.36032 +0.12572 +0.55654 +0.33438 +0.086464 +0.14357 +0.088183 +0.030601 +0.01347 +0.030183 +0.068391 +0.06299 +0.16731 +0.11754 +0.19204 +0.10179 +0.48884 +0.83021 +0.15179 +0.11309 +0.15335 +0.051284 +0.11109 +0.26902 +130.47 +111.1 +39.982 +324.16 +212.63 +80.125 +92.203 +198.71 +146.07 +139.22 +61.682 +2072.5 +1101.5 +1160.8 +2828.3 +2712.6 +144.74 +197.01 +317.23 +254.66 +614.69 +46.991 +276.81 +240.28 +421.74 +174.91 +123.19 +47.067 +30.73 +27.222 +0.79767 +0.93031 +0.6527 +0.18686 +0.57061 +0.16706 +0.39984 +0.35152 +0.18556 +0.26583 +0.35237 +0.091806 +0.032438 +0.030631 +0.025176 +0.026231 +0.24591 +1.3939 +0.51838 +0.32738 +0.16568 +0.097878 +0.25571 +0.86376 +0.17641 +0.033889 +0.014991 +0.026878 +0.087333 +0.16469 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/layer84_permy.geos b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/layer84_permy.geos new file mode 100644 index 00000000000..d83867f1511 --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/layer84_permy.geos @@ -0,0 +1,13200 @@ +0.064542 +0.034083 +0.033865 +12.584 +25.506 +49.557 +110.05 +3.1658 +1864.7 +554.89 +778.92 +166.98 +1152.9 +430.23 +940.06 +345.37 +229.37 +390.37 +744.79 +110.79 +189.92 +61.175 +45.341 +299.3 +268.93 +51.619 +25.666 +116.14 +0.10857 +0.30584 +0.11793 +0.097815 +0.18215 +0.13971 +0.091116 +0.046364 +0.10297 +0.079578 +0.013536 +0.03645 +0.10576 +0.45575 +0.19143 +0.081675 +521.47 +588.83 +425.18 +60.599 +71.636 +285.38 +361.31 +17.056 +47.555 +148.49 +65.429 +34.797 +111.85 +136.38 +98.327 +169.98 +0.11286 +0.10634 +0.081667 +0.052393 +32.541 +36.477 +166.46 +2237.7 +678.13 +492.44 +793.61 +285.87 +1633.4 +676.45 +371.46 +426.83 +379.78 +369.9 +288.81 +69.299 +67.002 +25.327 +39.998 +379.97 +257.87 +65.124 +28.595 +98.913 +0.28881 +0.33028 +0.25872 +0.1233 +0.048856 +0.22513 +0.37565 +0.026637 +0.059152 +0.034875 +0.01443 +0.019086 +0.11767 +0.099196 +0.07389 +0.034775 +432.54 +324 +52.078 +142.62 +195.34 +231.22 +246.73 +317.3 +61.988 +65.189 +258.83 +34.475 +138.53 +276.58 +166.55 +293.29 +0.065883 +0.097745 +0.20938 +0.79875 +0.49302 +0.23443 +44.765 +200.05 +608.83 +190.16 +566.79 +230.07 +998.9 +648.59 +145.2 +617.66 +574.48 +340.95 +139.57 +73.181 +85.964 +22.285 +47.058 +120.34 +235.96 +27.214 +24.529 +70.772 +0.63261 +0.18382 +0.19455 +0.12733 +0.086306 +0.15792 +0.23827 +0.38131 +0.15722 +0.24469 +0.043473 +0.12284 +0.25926 +0.087617 +0.036858 +0.055697 +246.6 +376.72 +87.035 +252.94 +338.94 +141.44 +308.2 +237.84 +47.03 +90.055 +141.26 +38.305 +423.1 +231.6 +144.91 +193.52 +0.19582 +0.029963 +0.16623 +0.18874 +0.63653 +0.13589 +0.46928 +0.069859 +84.093 +297.66 +709.97 +332.23 +1179.3 +960.02 +99.835 +679.55 +690.79 +230.29 +64.782 +74.962 +63.969 +29.326 +31.055 +62.858 +78.211 +49.509 +27.538 +52.3 +0.14683 +0.073425 +0.079791 +0.23118 +0.15686 +0.37766 +0.23192 +0.18254 +0.13246 +0.36985 +0.28115 +0.45961 +0.2039 +0.14442 +0.12089 +0.035193 +51.816 +279.09 +98.52 +165.48 +205.67 +84.122 +126.41 +144.61 +141.12 +84.454 +98.735 +29.543 +30.702 +32.005 +64.901 +190.82 +0.24328 +0.045128 +0.27136 +0.17964 +0.28686 +0.31372 +0.10344 +0.027707 +65.548 +192.02 +1056.6 +451.14 +568.55 +884.24 +143.95 +218.63 +354.26 +223.68 +182.13 +73.648 +12.494 +23.241 +24.469 +120.55 +87.03 +59.859 +63.365 +57.563 +205.47 +0.10258 +0.036084 +0.22701 +0.34276 +0.15466 +0.037823 +0.042638 +0.41338 +0.31336 +1.0557 +0.074098 +0.12464 +0.063393 +0.15806 +0.071952 +0.1078 +161.37 +108.25 +289.25 +122.91 +205.05 +483.29 +86.51 +38.502 +49.36 +34.694 +21.44 +222.37 +340.5 +35.465 +382.73 +0.17405 +0.24344 +0.21956 +0.11204 +0.50225 +0.40387 +0.13347 +44.621 +49.595 +205.14 +110.97 +231.59 +598.07 +241.89 +127.55 +257.68 +301.45 +264.14 +205.78 +945.86 +406.89 +33.532 +88.773 +139.35 +43.266 +31.504 +50.983 +70.095 +116.72 +0.012884 +0.021406 +0.11139 +0.13991 +0.23014 +0.083808 +0.14631 +0.4154 +0.39946 +0.58834 +0.10903 +0.023152 +0.062313 +0.44326 +0.042737 +0.11187 +0.20606 +833.41 +200.2 +185.46 +139.76 +433.92 +115.96 +43.992 +58.488 +38.38 +15.999 +142.26 +272.44 +125.73 +374.02 +0.36356 +0.23023 +0.34597 +0.57646 +0.69528 +0.18271 +12.786 +22.28 +72.075 +293.26 +69.144 +144.89 +185.07 +65.641 +227.53 +69.682 +112.23 +163.93 +110.52 +557.42 +414.41 +44.922 +90.015 +218.6 +32.666 +31.722 +28.023 +82.649 +82.841 +0.2781 +0.15826 +0.2424 +0.26436 +0.079702 +0.068927 +0.1803 +0.22496 +0.30583 +0.92788 +0.13457 +0.011549 +0.072593 +0.26906 +0.1108 +1005.4 +403.63 +357.54 +179.15 +227.94 +169.22 +248.56 +256.55 +135.76 +46.386 +87.288 +80.658 +268.25 +110.56 +70.52 +354.73 +0.17062 +0.19122 +1.4683 +0.28591 +1.1344 +0.61433 +14.97 +31.062 +70.954 +232.54 +179.12 +120.54 +133.6 +89.496 +52.812 +379.81 +200.82 +100.85 +75.243 +157.67 +347.75 +206.1 +229.32 +114.01 +20.654 +33.827 +40.613 +76.305 +22.376 +63.505 +0.11355 +0.14114 +0.011373 +0.057265 +0.20586 +0.21325 +0.055662 +0.093884 +0.14534 +0.048081 +0.041314 +0.046246 +0.03562 +760.16 +1217 +745.93 +795.84 +99.913 +204.06 +123.77 +253.1 +204.19 +152.04 +138.02 +84.878 +82.619 +104.82 +76.898 +59.541 +152.44 +0.29373 +0.13717 +0.29431 +4.3611 +0.32076 +0.83081 +27.533 +64.722 +31.243 +177.8 +211.94 +158.24 +69.265 +56.738 +307.65 +339.36 +257.26 +60.568 +76.742 +169.22 +444.62 +208.19 +372.92 +89.071 +34.606 +36.319 +27.375 +106.42 +24.527 +75.613 +2362.9 +0.072295 +0.033354 +0.018601 +0.089319 +0.086002 +0.066354 +0.17864 +0.32434 +0.066334 +0.061923 +0.1465 +0.20517 +459.33 +444.1 +699.99 +768.6 +99.921 +170.93 +233.83 +1389.3 +377.83 +235.73 +251.35 +104.14 +64.791 +76.809 +0.16251 +0.24275 +0.030701 +0.45119 +0.20232 +0.5466 +0.65022 +0.55413 +0.10716 +46.39 +83.23 +37.374 +213.88 +51.885 +22.977 +74.532 +168.72 +187.73 +234.98 +232.28 +30.974 +294.42 +566.89 +529.52 +245.32 +313.32 +257.05 +385.16 +157.47 +129.16 +135.72 +27.896 +78.059 +3242.2 +975.66 +0.072112 +0.029737 +0.06779 +0.035362 +0.083346 +0.22955 +0.071457 +0.12459 +0.11444 +3172.4 +278.98 +589.88 +584.53 +403.27 +750.9 +217.59 +194.54 +164.41 +467.93 +1360.8 +290.77 +253.07 +355.59 +196.4 +326.85 +0.14956 +0.11366 +0.15315 +0.37969 +0.23949 +0.10672 +0.079027 +0.080941 +0.064121 +72.658 +43.561 +50.816 +137.24 +25.553 +16.117 +53.033 +347.26 +201.64 +299.23 +176.54 +33.877 +462.13 +136.41 +112.91 +138.66 +221.94 +188.74 +803.49 +116.76 +912.63 +127.61 +125.75 +166.11 +101.56 +911.79 +186.47 +0.08453 +0.039313 +0.049767 +0.40395 +0.10691 +0.016847 +161.96 +577.41 +2099.7 +241.99 +319.12 +2261.6 +2442.1 +209.19 +146.51 +159.46 +348.49 +263.67 +462.89 +129.9 +107.08 +133.09 +711.3 +275.4 +0.055833 +0.14019 +0.06268 +0.20509 +0.2143 +0.25294 +0.52994 +0.079145 +0.090655 +47.828 +26.751 +31.94 +55.881 +172.71 +31.025 +83.53 +472.45 +473.52 +180.58 +68.023 +18.186 +513.8 +87.376 +62.507 +172.49 +268.2 +211.04 +371.53 +41.53 +79.049 +533.62 +218.18 +33.722 +149.07 +76.799 +505.42 +0.028038 +0.12757 +0.098478 +0.40759 +0.23775 +352.3 +361.97 +507.75 +1063 +463.21 +934.6 +1800.2 +2441.5 +161.96 +71.926 +129.75 +276.79 +752.58 +373.23 +55.897 +222.43 +267.63 +855 +547.59 +754.28 +0.12624 +0.056341 +0.091799 +0.18029 +0.54194 +0.17822 +0.24298 +0.22995 +115.58 +55.764 +51.966 +60.55 +83.883 +40.962 +111.47 +437.03 +625.37 +60.861 +110.38 +35.098 +344.29 +228.48 +232.04 +284.52 +453.57 +223.13 +454.08 +79.732 +78.156 +327.48 +269.76 +928.72 +373.5 +51.307 +107.01 +0.027685 +0.049666 +0.1022 +0.21973 +60.967 +291.13 +482.85 +889.98 +1986.5 +279.88 +2971.5 +1887.5 +1686.1 +177.06 +246 +239.78 +133.89 +475.95 +498.08 +73.064 +150.48 +197.38 +1038 +828.51 +0.054693 +0.027247 +0.042157 +0.034732 +0.01816 +0.1158 +0.22036 +0.023251 +0.041459 +224.57 +76.117 +70.432 +230.56 +57.266 +57.341 +263.94 +298.04 +535.68 +44.06 +238 +335.79 +115.85 +1013.3 +547.52 +490.85 +748.42 +196.51 +235.21 +38.992 +174.13 +614.47 +508.34 +1093.2 +207.76 +76.966 +2303.5 +6468.3 +3378 +3568.4 +232.79 +102.71 +154.52 +296.64 +666.62 +0.044901 +0.033646 +0.074568 +1040.8 +1456 +484.49 +372.73 +165.15 +117.14 +69.967 +328.01 +411.26 +271.49 +2909.1 +1338.5 +0.10492 +0.09618 +0.17501 +0.042574 +0.045451 +0.032037 +0.064184 +0.13178 +0.045783 +0.1872 +380.62 +112.71 +86.495 +250.1 +79.037 +90.322 +220.58 +328.97 +146.02 +33.509 +428.75 +129.38 +131.41 +141.74 +518.04 +652.16 +824.41 +224.94 +455.9 +903.34 +368.35 +741.47 +394.17 +825.35 +719.21 +126.73 +53.909 +1682.2 +3920.8 +5337.6 +7227.1 +63.056 +196.31 +207.31 +0.018731 +0.081244 +0.03119 +0.034039 +1053 +1256.4 +457.57 +714.14 +210.8 +436.48 +71.696 +183.29 +303.12 +691.12 +467.88 +0.043608 +0.057146 +0.34246 +0.13845 +0.050325 +0.10604 +0.022569 +0.10474 +0.17147 +0.26691 +0.66749 +375.88 +96.477 +186.03 +255.69 +93.254 +55.775 +109.36 +129.54 +117.51 +30.112 +702.12 +153.61 +217.21 +2400.3 +390.82 +528.63 +678.78 +169.76 +902.57 +786.16 +583.42 +1555.4 +273.07 +796.46 +692.55 +157.24 +64.409 +693.8 +1953.5 +4344.9 +4908.8 +6861.6 +115.13 +196.53 +0.010065 +0.005226 +0.015142 +0.044592 +841.66 +701.51 +569.97 +1404.1 +420 +945.03 +91.569 +372.7 +479.58 +867.86 +0.14671 +0.022754 +0.058072 +0.25578 +0.373 +0.12615 +0.10488 +0.040757 +0.038922 +0.1141 +1.5126 +5.2666 +0.50732 +1.732 +57.488 +162.49 +111.95 +109.48 +146.69 +203.31 +60.671 +24.116 +83.11 +271.01 +83.895 +1165.8 +506.66 +704.71 +537.11 +226.38 +486.78 +850.98 +792.5 +221.86 +97.752 +287.8 +506.4 +259.7 +63.291 +259.46 +281.67 +4594.3 +2977.5 +5929.5 +154.72 +0.18093 +0.023153 +0.013063 +0.062635 +1468.4 +93.999 +988.36 +1146.2 +1007.5 +631.03 +1563.5 +555.79 +373.58 +897.79 +510.13 +1.5394 +0.071805 +0.41543 +0.22775 +0.16103 +0.14905 +0.3836 +0.059474 +0.068608 +0.37691 +0.56713 +4.4797 +0.21818 +0.065353 +45.733 +83.197 +154.54 +98.953 +44.568 +100.51 +36.408 +38.667 +107.35 +26.764 +36.915 +691.38 +423.64 +503.46 +211.26 +398.14 +109.26 +933.74 +664.61 +245.23 +97.1 +911.37 +794.12 +234.75 +101.76 +94.315 +292.58 +825.85 +2257.3 +1809.7 +65.881 +1.2157 +0.20489 +0.041237 +0.055386 +0.22325 +252.36 +123.01 +3059.1 +383.73 +219.59 +460.94 +1039.4 +352.3 +127.91 +0.057797 +0.60867 +0.15544 +0.21043 +0.25787 +0.2688 +0.20647 +0.5459 +0.072486 +0.041144 +0.061576 +0.37612 +0.22198 +0.061339 +0.018407 +77.257 +137.34 +199.79 +93.143 +69.812 +97.414 +41.885 +30.648 +41.72 +51.445 +670.2 +421.82 +327.57 +761.36 +250.34 +271.42 +128.38 +230.9 +86.811 +177.7 +0.046207 +1417.1 +447.81 +359.22 +225.09 +85.249 +398.68 +1450.6 +1573.5 +3203.5 +2303.9 +0.085812 +0.12855 +0.058119 +0.058183 +82.827 +338.13 +24.439 +351.91 +600.56 +371.71 +288.02 +777.4 +126.96 +135.74 +748.38 +0.28827 +0.92401 +0.099892 +0.063414 +0.047237 +0.23694 +0.1953 +0.016815 +0.062956 +0.10603 +0.20299 +0.068023 +0.015586 +0.079782 +0.069472 +70.9 +168.8 +83.003 +66.23 +89.389 +39.068 +11.904 +33.453 +148.55 +689.3 +510.42 +255.16 +396.9 +233.01 +234.7 +148.23 +192.56 +132.09 +377.94 +20000 +641.09 +535.18 +422.13 +203.7 +103.14 +164.08 +384.23 +3595.2 +3326.6 +0.43644 +0.87682 +0.21329 +216.08 +67.867 +88.226 +332.5 +40.323 +75.919 +571.44 +681.47 +703.88 +751.92 +96.307 +55.034 +817.01 +857.88 +1.8641 +0.30399 +0.023181 +0.095362 +0.085263 +0.02839 +0.069068 +0.045199 +0.077594 +0.14852 +0.08044 +0.045626 +0.029042 +0.062378 +38.99 +97.05 +125.67 +129.75 +182.08 +45.691 +58.096 +471.37 +87.832 +407.89 +519.4 +270.96 +490.63 +379.78 +260.58 +235.88 +4558.9 +101.19 +220.15 +20000 +183.09 +491.78 +784.9 +192.65 +266.35 +321.63 +260.47 +3947.8 +0.15472 +0.1247 +0.086955 +0.15396 +17.211 +197.68 +92.417 +434.23 +30.135 +188.99 +381.47 +3151.1 +1147.3 +222.12 +171.38 +7.9534 +559.02 +608.7 +281.97 +0.22344 +0.082356 +0.052349 +0.04474 +0.006468 +0.085523 +0.055831 +0.16622 +0.071888 +0.051486 +0.010634 +0.10723 +94.868 +34.1 +112.63 +81.7 +125.74 +102.26 +30.577 +327.97 +341.43 +87.525 +262.53 +432.91 +77.231 +391.52 +312.13 +246.19 +3986.3 +3196.6 +391.99 +250 +217.76 +199.5 +1131.3 +322.69 +290.15 +257.5 +376.57 +0.32552 +0.20756 +0.41813 +0.46419 +0.42621 +10.378 +15.666 +43.303 +927.56 +735.71 +103.51 +149.84 +381.74 +2065.3 +108.7 +155.15 +74.238 +9.7458 +564.77 +739.74 +318.89 +254.18 +0.05016 +0.15938 +0.44953 +0.64601 +0.021304 +0.046599 +0.037551 +0.050755 +0.049153 +670.11 +313.38 +202.78 +25.986 +138.02 +74.498 +167.35 +896.58 +477.79 +617.6 +187.95 +76.598 +386.53 +705.47 +172.13 +444.19 +508.81 +1394.4 +2491.8 +140.81 +363.63 +1131.9 +402.83 +125.62 +989.79 +768.08 +217.83 +93.863 +0.073146 +0.1392 +0.066525 +0.064315 +0.086 +0.062137 +11.013 +11.121 +89.624 +505.35 +227.03 +59.997 +179.86 +623.13 +167.34 +145.28 +106.3 +183.74 +23.414 +353.03 +346.34 +118.33 +0.38988 +0.048508 +0.14228 +0.059671 +0.058192 +0.15036 +0.42229 +0.22523 +0.10655 +0.17156 +629.91 +505.61 +227.95 +55.159 +147.97 +85.203 +1598 +1243.7 +1036.3 +168.31 +141.9 +180.92 +582.24 +442.22 +261.19 +309.28 +5384.5 +0.29577 +148.73 +99.551 +213.17 +735.85 +767.04 +157.13 +49.371 +999.46 +467.36 +0.15842 +0.031487 +0.040931 +0.20878 +0.15259 +0.33171 +11.363 +8.2247 +6.9178 +208.51 +238.45 +246.52 +124.96 +57.279 +103.69 +133.34 +154.73 +198.42 +606.44 +49.994 +543.56 +310.61 +254.47 +0.094992 +0.086519 +0.12653 +0.068546 +0.09167 +0.047976 +0.080055 +0.18503 +0.065935 +436.44 +383.64 +177.41 +189.57 +89.964 +289.68 +975.21 +341 +109.23 +51.145 +165.32 +79.5 +220.37 +1144.4 +564.87 +6233.4 +326.03 +258.97 +80.484 +104.37 +70.665 +172.14 +607.39 +1315.4 +2035.7 +411.98 +953.81 +0.037991 +0.056282 +0.039962 +0.059559 +0.1805 +0.27062 +1.4387 +4.6608 +138.79 +113.75 +10.047 +15.914 +60.87 +56.757 +23.284 +144.9 +133.17 +242 +76.539 +366.93 +67.01 +439.08 +601.39 +292.76 +1679.2 +0.20646 +0.090226 +0.051762 +0.16651 +0.063797 +0.03858 +0.053665 +0.053837 +342.42 +357.26 +0.14388 +207.49 +364.89 +243.9 +677.55 +177.9 +172.02 +39.464 +144.03 +163.96 +106.44 +9344.4 +7339.1 +134.06 +283.62 +697.86 +107.66 +112.39 +175.22 +626.53 +0.13755 +992.8 +1401 +411.5 +847.72 +1832.8 +0.26055 +0.37582 +0.081309 +0.17563 +0.12407 +625.01 +1241.6 +80.451 +17.904 +18.647 +6.8496 +2.6433 +84.082 +46.953 +144.48 +145.76 +229.34 +112.21 +175.66 +133.41 +493.73 +777.01 +438.79 +2223.4 +0.24289 +0.090909 +0.054286 +0.035886 +0.042054 +0.017021 +0.036003 +0.033485 +0.056762 +714.37 +112.05 +302.28 +827.07 +292.39 +458.93 +363.44 +172.85 +108.84 +252.63 +234.15 +12024 +102.83 +134.89 +254.97 +507.3 +693.86 +234.78 +224.19 +0.21142 +0.15445 +0.069956 +494.82 +610.78 +622.52 +1029.1 +1772.1 +301.51 +0.18088 +0.12615 +0.083816 +332.2 +0.045379 +0.018357 +0.024315 +14.364 +14.716 +7.4866 +58.744 +77.545 +79.97 +223.5 +171.29 +236.06 +163.15 +255.84 +516.74 +0.011899 +717.16 +296.42 +2101.7 +733.89 +0.012212 +0.024235 +0.027301 +0.02557 +0.010744 +0.024276 +0.04748 +94.542 +80.874 +99.301 +307.32 +868.22 +682.78 +437.97 +482.38 +372.26 +307.69 +36.34 +155.75 +81.583 +127.78 +106.65 +101.24 +424.24 +433.57 +202.87 +0.13553 +0.020352 +0.054023 +0.037423 +0.023142 +372.85 +519 +526.58 +834.26 +298.72 +90.51 +597.77 +1087.5 +0.026311 +0.032221 +0.067858 +0.037855 +0.067948 +0.059987 +104.08 +95.129 +147.7 +143.52 +323.02 +148.59 +487.15 +596.4 +863.81 +937.84 +355.45 +198.74 +179.55 +2036.5 +0.017805 +0.027843 +0.037913 +0.039088 +0.02631 +0.022821 +235.55 +117.99 +43.88 +90.053 +129.31 +249.62 +1078.8 +1344 +496.9 +430.09 +374.78 +29.099 +94.298 +143.63 +162.17 +142.08 +71.208 +92.798 +222.48 +2987.3 +0.04223 +0.023116 +0.16845 +0.029541 +0.043063 +988.46 +276.95 +668.82 +306.4 +721.62 +381.79 +817.32 +2100 +7.8004 +0.029002 +0.063596 +0.032126 +164.94 +166.56 +162.23 +144.35 +91.474 +103.39 +87.628 +244.26 +319.17 +553.78 +654.83 +461.8 +511.82 +208.13 +340.31 +392 +786.86 +0.036235 +0.080712 +0.089838 +0.16975 +0.051504 +227.24 +147.28 +82.719 +23.627 +46.817 +132.27 +188.31 +860.68 +575.89 +288.7 +763.1 +73.746 +116.37 +96.039 +164.91 +73.634 +144.24 +70.428 +70.998 +3815.2 +2041.4 +0.13388 +0.13954 +0.13916 +0.023716 +0.019203 +921.26 +287.58 +790.68 +1085 +998.12 +371.65 +545.76 +1367.7 +11.845 +0.011215 +5747.8 +10258 +841.05 +117.53 +153.13 +169.41 +120.66 +144.86 +285.1 +289.18 +130.82 +217.66 +205.8 +288.47 +432.23 +181.83 +251.83 +1077.2 +736.78 +0.32814 +0.064353 +0.18512 +0.041463 +120.27 +190.09 +106.56 +93.094 +25.747 +79.519 +192.22 +230.07 +1161.7 +550.42 +341.85 +177.41 +134.28 +177.31 +105.5 +164.13 +120.76 +59.415 +40.681 +45.245 +2568.5 +3029.3 +4473 +8542.1 +0.022298 +0.035673 +0.035346 +977.49 +394.62 +913.86 +646.09 +2371.4 +297.66 +279.83 +977.18 +124.68 +0.031991 +4585.1 +9669.5 +970.54 +171.93 +84.455 +211.19 +1630 +2793 +465.26 +144.91 +148.96 +147.98 +133.03 +416.29 +324.25 +118.46 +236.1 +1085.5 +790.89 +0.3891 +0.13582 +0.083521 +0.044139 +100.48 +89.16 +120.24 +87.716 +73.05 +68.88 +144.98 +387.36 +938.04 +528.41 +1160 +458.76 +175.31 +148.55 +59.324 +170.47 +178.92 +48.419 +70.68 +4090.7 +5340.3 +3119.6 +6201.5 +8242.8 +16749 +12469 +102.8 +660.59 +217.71 +879.71 +649.42 +2004.5 +212.34 +288.94 +225.95 +308.23 +562.39 +5784.4 +5212.6 +351 +125.83 +75.04 +476.05 +0.054004 +619.38 +227.82 +191.05 +71.829 +204.96 +161.22 +178.01 +193.32 +163.02 +433.27 +1454.6 +754.13 +271.06 +0.019848 +0.11036 +0.047296 +106.88 +95.278 +95.915 +111.79 +50.32 +153.07 +200.04 +365.17 +1101.2 +729.67 +1837.1 +0.02878 +195.7 +202.86 +72.614 +212.57 +189.85 +51.696 +176.23 +150.16 +6093.7 +3746.3 +4104.9 +18194 +33.859 +83.221 +62.64 +272.86 +306.46 +910.8 +624.76 +1693.9 +175.95 +291.47 +156.22 +514.46 +696.38 +345.06 +4924.7 +730.5 +211.28 +210.53 +895.53 +0.10021 +18.802 +183.56 +236.6 +65.828 +161.85 +79.685 +318.64 +453.92 +841.64 +805.6 +1730.2 +751.39 +190.02 +0.048484 +0.050683 +0.038711 +244.93 +180.15 +90.256 +106.18 +51.704 +591.79 +180.03 +479.85 +496.25 +1132.1 +1525 +46.547 +156.02 +224.87 +129.04 +391.41 +260.57 +53.318 +82.291 +19.442 +66.122 +4506.7 +271.49 +105.16 +60.001 +155.7 +91.994 +244.82 +966.31 +514.52 +338.86 +1287.5 +104.38 +271.78 +281.53 +894.33 +757.46 +334.09 +5967 +1082.9 +256.95 +157.1 +1930.3 +0.16706 +0.23357 +20.546 +135.89 +57.231 +71.034 +63.959 +268.83 +538.06 +364.27 +1327.3 +577.67 +453.41 +471.46 +0.032577 +0.096693 +0.030402 +0.094 +0.074792 +78.624 +65.998 +39.28 +306.65 +344.83 +510.79 +772.37 +694.05 +0.03337 +69.284 +270.64 +290.06 +142.75 +261.81 +144.63 +35.737 +83.141 +27.761 +1207.6 +538.28 +198.34 +222.84 +161.79 +336.02 +119.24 +226.28 +747.55 +1313.5 +339.85 +831.74 +102.72 +0.18271 +0.088591 +369.18 +764.11 +302.49 +30.472 +2402.1 +432.65 +316.17 +2418.3 +0.35435 +33.611 +32.474 +98.578 +117.95 +91.226 +102.23 +233.26 +279.37 +279.32 +280.64 +370.97 +731.11 +595.38 +889.63 +0.36594 +0.019786 +0.10423 +0.040005 +32.878 +117.14 +73.209 +232.31 +252.47 +651 +183.84 +0.10801 +27.506 +188.62 +509.14 +266.7 +168.45 +172.56 +109.56 +55.617 +252.76 +607.03 +865.22 +472.78 +268.46 +632.95 +328.74 +331.95 +83.728 +261.86 +661.03 +1607.8 +329.39 +0.39644 +0.43631 +0.39884 +0.37352 +44.636 +260.62 +246.54 +541.03 +128.29 +3362.3 +602.47 +2247.1 +2084.1 +19.81 +32.902 +110.82 +289.74 +271.99 +370.5 +156.57 +148.43 +271.8 +246.04 +308.34 +513.93 +437.25 +722.29 +0.055349 +0.064215 +0.060211 +35.199 +43.349 +82.321 +116.22 +259.09 +300.14 +914.46 +0.051738 +0.04402 +845.58 +114.58 +867.06 +171.51 +100.07 +45.13 +49.633 +600.8 +400.96 +1189.2 +438.15 +333.41 +334.24 +506.34 +1009.4 +329.67 +193.95 +650.63 +20000 +9786.2 +14168 +0.38846 +0.26615 +0.15357 +0.16432 +0.22051 +284.96 +503.52 +226.77 +172.01 +21.474 +285.29 +2905.1 +2362.1 +1942.4 +83.699 +73.349 +222.87 +209.62 +370.26 +269.28 +1046.7 +189.19 +151.17 +400.13 +284.85 +1056.1 +353.95 +0.055006 +0.037158 +0.058991 +53.239 +74.838 +61.747 +135.69 +136.02 +768.77 +653.57 +1313.4 +1847.1 +958.28 +44.354 +273.64 +80.772 +66.911 +66.443 +15.835 +310.34 +831.23 +874.79 +260.78 +201.9 +514.62 +357.33 +921.11 +20000 +20000 +20000 +20000 +333.48 +401.43 +404.68 +255.02 +0.080324 +0.13234 +0.13573 +0.068013 +140.55 +115.24 +186.85 +25.299 +20.742 +4288.7 +2670.6 +1431.7 +2539.6 +1994.2 +163.74 +126.74 +399.95 +995.58 +896.65 +446.85 +108.79 +239.23 +284.56 +511.5 +543.92 +0.45725 +0.092232 +230.78 +142.68 +65.559 +185.2 +158.98 +306.39 +1413.1 +0.07376 +0.090521 +0.16032 +1730.2 +37.544 +178.01 +141.25 +115.97 +51.94 +15.798 +542.98 +640.16 +1060 +245.69 +0.32582 +0.32508 +0.15372 +20000 +13832 +16616 +20000 +20000 +17596 +1783.3 +563.1 +180.11 +696.35 +0.059353 +159.76 +75.456 +118.69 +258.25 +1071 +129.54 +100.61 +9.3211 +1943.4 +2179.4 +2620 +1787.8 +154.85 +104.89 +45.203 +277.6 +885.44 +383.8 +79.739 +94.45 +904.37 +651.6 +0.067856 +1.7106 +0.041091 +170.08 +53.609 +83.895 +228.6 +157 +445.71 +1656.3 +215.4 +214.53 +323.24 +263.59 +722.11 +1039.8 +128.05 +172.71 +35.944 +11.673 +384.68 +0.054976 +0.056484 +0.54125 +0.3867 +0.40171 +0.29226 +20000 +20000 +8921.1 +20000 +20000 +12660 +6466.7 +1395.4 +147.94 +356.31 +0.05831 +0.24296 +86.243 +153.72 +331.3 +674.56 +551.37 +132.56 +13.224 +9.2287 +1452 +1480.5 +1856.3 +2736.7 +924.97 +42.436 +61.555 +114.05 +89.524 +156.76 +59.733 +584.63 +384.05 +0.092109 +0.22831 +0.29556 +109.33 +107.95 +123.46 +112.61 +120.59 +422.5 +2442.1 +3099.1 +307.89 +538.93 +460.33 +408.81 +2071.4 +4612.8 +225.9 +28.076 +17.87 +11.689 +9.242 +0.25543 +0.26083 +0.18224 +0.56139 +15142 +20000 +20000 +10371 +20000 +20000 +49.477 +36.952 +1063.7 +202.47 +196.9 +0.21012 +0.097823 +64.417 +174.78 +533.15 +413.96 +11.479 +68.185 +43.638 +13.485 +10.291 +1656.3 +1165.1 +2048.9 +102.33 +68.549 +71.977 +238.51 +103.31 +101.99 +48.875 +43.378 +0.13187 +0.046404 +0.16419 +0.64175 +0.29613 +49.225 +195.35 +288.27 +177.93 +207.91 +1662.8 +2651.5 +219.76 +498.8 +594.19 +527.32 +2374.4 +3434.4 +262.9 +49.239 +15.312 +9.3444 +5.436 +0.076231 +0.017327 +0.36808 +20000 +13640 +20000 +20000 +9387.2 +20000 +64.693 +36.159 +23.757 +771.4 +0.081627 +0.033605 +0.031971 +89.904 +79.553 +127.75 +395.49 +11.296 +43.573 +91.118 +47.1 +77.163 +17.461 +63.621 +180.78 +2007.6 +181.5 +145.37 +35.083 +170.21 +95.539 +60.156 +41.245 +23.391 +69.86 +0.307 +0.077237 +0.53307 +0.58566 +0.23657 +77.484 +112.25 +930.2 +143.83 +1019.6 +2324.4 +362.98 +243.42 +419.78 +1374 +5187.8 +3194.1 +398.6 +47.299 +9.0425 +13.18 +4.9446 +0.11462 +0.07608 +0.11186 +20000 +20000 +20000 +13096 +4292.8 +20000 +20.069 +25.817 +46.058 +38.489 +0.047873 +0.038792 +0.20183 +0.60446 +0.067169 +0.18499 +0.084948 +12.808 +60.674 +79.399 +53.937 +20.307 +20.734 +92.872 +180.4 +980.75 +299.44 +113.78 +25.021 +41.784 +65.546 +64.539 +55.268 +32.824 +59.059 +75.303 +0.20485 +0.30454 +0.80804 +0.30306 +0.21426 +272.83 +488.85 +639.85 +1251 +1381.8 +756.77 +224.57 +542.77 +2310.6 +4436 +251.9 +57.621 +0.12822 +22.411 +4.2519 +6.105 +34.843 +6.9776 +0.60394 +20000 +19465 +17455 +4239.9 +4172.6 +16588 +65.404 +32.694 +65.236 +78.405 +0.036713 +0.19119 +0.31752 +0.56851 +0.039968 +0.029245 +30.799 +26.298 +227.98 +129.25 +61.616 +26.855 +33.661 +93.855 +116.68 +700.72 +213.94 +126.5 +25.579 +84.178 +49.549 +8.5375 +28.304 +26.286 +106.17 +45.605 +0.049351 +0.17173 +0.69811 +0.052192 +0.35938 +243.35 +315.11 +1604.8 +3327.6 +1522.5 +3306.4 +687.62 +412.38 +1979.8 +571.65 +891.01 +95.9 +779.36 +871.37 +3.5137 +9.9101 +32.84 +15.585 +25.363 +20000 +8196.4 +8226.6 +3601.3 +7732.2 +5508.6 +5874.1 +23.066 +51.827 +60.333 +154.1 +0.71506 +0.056885 +0.11326 +0.015941 +197.96 +62.482 +23.728 +213.73 +244.99 +26.328 +9.1281 +45.411 +120.23 +96.569 +907.68 +540.16 +68.777 +94.686 +65.724 +46.961 +12.289 +27.698 +29.001 +108.36 +49.029 +47.646 +0.27776 +0.82964 +0.06854 +99.124 +77.718 +140.85 +1004.8 +7960.1 +2334.2 +4649.5 +1402.8 +1298.7 +1638.8 +0.072125 +688.5 +2079.8 +584.88 +3649 +4.3504 +10.351 +43.181 +21.816 +11.112 +19465 +9088.5 +8617.2 +3232.9 +3562.4 +2620.5 +2983.7 +0.10192 +0.050717 +0.11496 +30.927 +31.204 +77.521 +0.055553 +471.38 +179.76 +100.76 +47.416 +415.41 +29.07 +19.549 +12.258 +52.935 +81.248 +104 +1043.8 +314.65 +138.76 +253.09 +101.64 +56.527 +9.4114 +12.099 +86.919 +145.69 +84.334 +59.532 +3.5592 +1.4952 +0.20445 +126.68 +112.03 +119.11 +351.73 +1289.2 +1421.1 +1711.5 +2364.9 +2012.4 +2515.3 +1119.9 +0.028167 +1173.3 +1219.5 +3030.7 +6.4432 +24.535 +40.614 +20.341 +10.027 +33.453 +5069.9 +4820.1 +4278.2 +5420.9 +1473.5 +0.057922 +0.22536 +0.10497 +0.16221 +0.10651 +0.021999 +433.08 +700.8 +856.04 +361.87 +243.95 +115.59 +55.019 +29.417 +9.5029 +9.9344 +45.165 +166.51 +46.815 +879.39 +193.78 +128.07 +179.34 +108.69 +135.75 +5.5524 +20.318 +49.264 +85.334 +165.48 +63.665 +0.84262 +0.59375 +0.30898 +0.042635 +72.153 +204.03 +130.92 +637.33 +230.95 +2356.6 +1382.4 +1872.7 +1943.6 +20.261 +705.67 +873.58 +1404.3 +15.366 +2.9473 +60.206 +45.805 +26.319 +10.562 +19.043 +29.694 +2600.1 +2673.8 +0.081876 +0.043923 +0.2819 +0.11478 +0.028511 +0.084036 +2.7731 +134.4 +185.52 +112.87 +510.91 +520.47 +345.36 +0.063346 +73.226 +38.148 +9.8193 +11.886 +38.157 +1353.6 +1987.7 +272.93 +203.1 +116.25 +136.02 +105.43 +155.47 +5.4723 +18.547 +32.067 +182.26 +90.351 +109.49 +0.81705 +0.34805 +0.038671 +0.062894 +128.42 +215.59 +178.89 +915.24 +193.08 +886.74 +2050.6 +1852.2 +852.21 +163.03 +1351.8 +553.68 +32.529 +15.394 +7.4316 +33.642 +26.94 +47.707 +16.751 +21.442 +22.55 +1174.5 +2916.1 +0.055861 +0.021274 +0.035199 +0.12111 +0.030879 +0.065266 +7.5117 +74.467 +177.32 +281.32 +281.42 +577.49 +0.050091 +0.18737 +0.1568 +28.529 +27.63 +2517 +738.1 +933.11 +871.79 +320.2 +157.03 +134.77 +168.69 +435.01 +652.92 +1859.8 +925.77 +1486.1 +1661.3 +4411.9 +46.269 +0.20478 +0.39581 +0.14735 +0.025938 +0.007892 +169.87 +198.28 +784.71 +2717.8 +1377.4 +3238.6 +5057.7 +695.24 +195.7 +1475 +1.9986 +13.711 +16.673 +35.938 +15.221 +20.127 +65.248 +20.669 +39.491 +51.869 +1473.4 +0.024469 +0.049945 +0.47797 +0.054648 +0.032764 +0.081617 +0.012342 +10.976 +113.37 +468.65 +442.29 +271.33 +1267.8 +0.02819 +0.053603 +0.054862 +43.035 +350.07 +1881 +1500.1 +950.93 +515.64 +479.51 +1144 +1023 +592.2 +329.2 +947.42 +973.82 +1447.6 +2677.9 +4213.7 +1444.8 +11079 +0.030241 +0.069073 +0.036347 +0.03097 +0.058345 +0.066494 +175.42 +3026.1 +1156.2 +2183 +2936.2 +2181.8 +832.18 +153.02 +706.54 +3.2145 +9.2865 +11.159 +17.896 +17.044 +23.973 +85.297 +34.483 +88.593 +39.678 +0.21368 +0.032631 +0.050632 +1.04 +1.1297 +0.059103 +0.077958 +0.11299 +23.192 +35.882 +438.07 +225.29 +411.25 +791.82 +0.039732 +0.069966 +0.071924 +247.34 +634.64 +2155.8 +872.2 +861.18 +112.31 +98.951 +431.1 +1775.3 +1553 +694.85 +1883 +1581.8 +910.39 +2078.4 +2836.2 +3505.7 +553.37 +0.068438 +0.0474 +0.081545 +0.077128 +0.14198 +0.09065 +0.15977 +2837.4 +1414.8 +1445.8 +6372.8 +4334.1 +1119 +15.122 +11.556 +2.4852 +20.439 +21.996 +28.635 +27.434 +24.46 +138.18 +62.951 +85.102 +143.21 +0.058604 +0.022878 +0.019812 +0.19787 +0.48935 +0.030584 +0.022982 +0.050755 +21.166 +40.382 +159.58 +195.45 +539.41 +193.07 +32.902 +18.827 +73.82 +257.64 +336.34 +2065.9 +58.382 +27.374 +91.346 +178.89 +738.15 +832.97 +2162.5 +234.65 +2058.4 +762.53 +1245 +544.75 +647.57 +285.73 +423.48 +0.13564 +0.15352 +0.23669 +0.21923 +0.040201 +0.052 +0.15072 +51.245 +1021.1 +2010.3 +3525.3 +6405.1 +1013.6 +14.065 +10.346 +3.1605 +15.167 +13.149 +25.728 +22.907 +35.685 +147.94 +23.242 +6649.4 +0.090554 +0.011954 +0.023624 +0.071026 +0.049531 +0.045962 +0.11707 +0.044904 +0.003453 +22.756 +77.47 +204.08 +127.37 +401.03 +291.2 +0.45181 +13.075 +151.26 +97.186 +47.583 +124.12 +75.046 +41.142 +91.46 +182.45 +976.96 +672.16 +687.45 +446.96 +717.36 +517.9 +938.71 +636.23 +1017.9 +515.14 +28.852 +0.21398 +0.24414 +0.17823 +0.55816 +0.085047 +0.31459 +0.09849 +0.079809 +54.552 +3577.8 +2515.6 +1908.1 +1342.8 +8.5413 +5.534 +4.4049 +11.797 +17.816 +20.836 +49.496 +43.551 +101.72 +35.164 +20.077 +0.16516 +0.017769 +0.080451 +0.094329 +0.030378 +0.063156 +0.013578 +0.022231 +0.013782 +0.015439 +127.72 +177.31 +158.85 +541.11 +667.76 +21.918 +117.12 +94.865 +93.768 +28.75 +94.018 +187.67 +111.14 +267.7 +364.4 +1178.8 +1002 +356.12 +982.39 +224.03 +983.79 +154.17 +186.08 +286.98 +88.52 +49.485 +0.17155 +0.021736 +0.29292 +0.12531 +0.42716 +0.91892 +0.20216 +0.38024 +0.52909 +410.89 +1841.5 +1972.3 +27.504 +14.306 +4.465 +11.739 +23.305 +23.479 +17.397 +139.09 +68.664 +82.785 +20.509 +20000 +0.02774 +0.013818 +0.071988 +0.039631 +0.054121 +0.059862 +0.020456 +0.021124 +0.059129 +0.09583 +99.545 +206.83 +121.91 +60.056 +20.178 +63.626 +81.151 +77.169 +63.101 +30.57 +69.759 +92.996 +134.47 +191.73 +170.07 +85.207 +967.41 +10.064 +465.78 +856.99 +543.12 +128.59 +104.4 +509.09 +142.32 +30.173 +0.018056 +0.069506 +0.21218 +0.25674 +0.29171 +0.041781 +0.082685 +0.12274 +0.28577 +514.54 +1315.1 +1134.4 +362.18 +36.529 +5.7158 +13.332 +22.623 +42.637 +27.724 +269 +60.291 +139.61 +20000 +13.809 +0.095444 +0.022126 +0.028104 +0.077474 +0.1055 +0.10579 +0.055851 +0.015427 +0.038735 +0.31868 +0.31549 +323.86 +16.54 +63.47 +33.31 +75.162 +30.931 +49.124 +104.16 +28.062 +64.962 +122.33 +1827.4 +111.14 +125.46 +175.3 +306.12 +622.04 +332.1 +756.65 +332.29 +99.591 +97.807 +617.16 +237.91 +0.075459 +0.09817 +0.036888 +0.050964 +0.079193 +0.13119 +0.13242 +0.14494 +0.031957 +0.17187 +589.53 +1208.2 +631.15 +655.41 +28.047 +1.964 +8.8037 +9.9004 +54.197 +108.86 +292.79 +127.63 +80.943 +20000 +23.485 +0.29382 +0.29789 +0.19878 +0.33962 +0.068099 +0.079467 +0.007288 +0.037506 +0.28082 +0.24958 +0.5342 +138.92 +43.91 +80.864 +75.525 +33.456 +43.745 +35.243 +68.509 +242.97 +111.28 +665.75 +1173.1 +293.92 +63.573 +117.11 +65.458 +437.87 +2401.5 +322.46 +248.79 +0.22628 +0.31325 +0.029867 +0.055075 +0.33352 +0.10808 +0.097961 +0.050965 +0.097559 +0.26001 +0.10609 +0.22272 +0.19604 +0.4478 +0.04884 +2688.5 +517.31 +1947.1 +2998.4 +3050.5 +19.024 +12.228 +36.285 +111.83 +933.51 +384.9 +9.5006 +6.9376 +32.749 +0.14588 +0.63414 +0.23036 +0.19989 +0.096949 +0.13617 +0.17872 +0.22419 +0.49506 +0.1051 +0.23654 +84.427 +69.478 +44.515 +66.773 +22.462 +24.596 +25.031 +51.575 +86.672 +89.458 +274.77 +1748.2 +347.16 +86.336 +160.91 +340.79 +905.96 +918.58 +895.08 +642.69 +0.61904 +0.26566 +0.022074 +0.009777 +0.038808 +0.046555 +0.049495 +0.072805 +0.039843 +412.94 +526.09 +127.76 +681.57 +1018.9 +2207.2 +3223 +460.75 +1377.1 +2722.3 +1138.6 +646.42 +8.875 +19.774 +160 +1286.4 +791 +533.6 +6.5705 +0.093492 +0.22165 +0.15121 +0.10654 +0.031967 +0.096837 +0.18621 +0.33583 +0.58797 +0.61404 +951.81 +750.49 +104.87 +48.109 +32.955 +53.962 +46.786 +15.958 +44.103 +1.6119 +3.2856 +109.51 +557.3 +439.74 +346.32 +119.83 +730.12 +422.69 +34.31 +547.07 +961.38 +1593.4 +657.75 +581.54 +0.086168 +0.016832 +0.14373 +0.036174 +0.12091 +718.86 +371.35 +523.68 +454.24 +395.61 +136.23 +74.243 +199.85 +2667 +339.19 +987.6 +1520.3 +1379.8 +699.36 +137.48 +65.923 +121.29 +1393 +530.65 +475.79 +263.41 +48.472 +0.14855 +0.070753 +0.16731 +0.46154 +0.46442 +0.60423 +0.70573 +0.62273 +0.59138 +2110.8 +644.45 +96.967 +24.153 +46.224 +80.647 +100.5 +22.023 +98.255 +2.7744 +3.3778 +1.4647 +407.64 +477.95 +109.45 +72.38 +0.18236 +704.03 +34.932 +45.493 +70.09 +1557.5 +1527.5 +945.92 +353.64 +0.009963 +0.078112 +0.015346 +1543.1 +814.47 +205.55 +734.18 +586.54 +0.22841 +195.42 +25.252 +4308.7 +2982.5 +381.27 +911.22 +1223.6 +1845.3 +804.02 +256.27 +114.24 +449 +790.84 +371.47 +358.03 +72.74 +111.62 +114.86 +0.092551 +0.33198 +0.24754 +2.024 +0.25662 +0.45082 +0.73555 +3636.6 +1332.3 +736.46 +38.128 +14.932 +75.837 +145.37 +49.5 +30.549 +106.6 +4.1381 +3.8719 +4.404 +55.712 +140.15 +113.51 +110.97 +275.25 +53.031 +27.742 +28.972 +791.02 +1455.2 +803.03 +850 +187.82 +107.59 +0.027439 +406.67 +1281.1 +704.42 +392.19 +472.2 +0.36087 +0.13702 +108.82 +48.818 +2490.1 +1403.5 +598.74 +1206.4 +703.75 +2806.5 +904.82 +339.44 +266.8 +644.84 +1400.6 +213.52 +141.4 +64.925 +59.615 +218.05 +143.68 +156.46 +0.48526 +0.10011 +0.11582 +0.73423 +1.2026 +1077.8 +2833.8 +16.095 +53.049 +132.48 +81.803 +69.067 +23.986 +49.768 +9.1437 +5.7868 +5.7691 +4.7154 +25.75 +67.965 +96.853 +242.67 +299.44 +51.551 +870.16 +1561.1 +542.65 +1431.2 +1150.8 +573.67 +195.28 +120.62 +0.023145 +870.83 +1111.1 +1623.7 +689.16 +0.3522 +0.27709 +0.1833 +84.574 +9416.9 +1964.3 +1223.8 +985.14 +1189.1 +463.23 +2388.6 +339.1 +599.4 +42.319 +24.308 +1690.2 +454.07 +242.87 +92.49 +73.505 +260.17 +109.93 +87.11 +108.57 +0.25691 +0.10643 +0.5489 +0.29398 +1.0334 +0.76915 +23.035 +50.295 +112.1 +42.311 +58.278 +32.938 +56.575 +20.429 +17.221 +4.8275 +3.405 +26.037 +109.89 +262.45 +308.71 +460.05 +424.02 +759.79 +1671.8 +336.06 +494.13 +717.63 +681.86 +289.17 +190.57 +0.18026 +711.92 +1083.2 +1827.5 +1171.1 +524.14 +0.061159 +0.031658 +605.27 +3347.5 +1701.1 +844.35 +456.99 +252.33 +316.51 +1033.5 +289.16 +70.727 +135.95 +582.36 +3156 +436.38 +248.56 +434.39 +52.032 +252.51 +129.67 +64.451 +71.064 +43.197 +0.029187 +0.072202 +0.38776 +2.4376 +181.32 +26.303 +42.276 +129.77 +32.753 +29.461 +99.841 +57.437 +28.765 +16.319 +8.3125 +7.3448 +23.654 +0.20924 +341.65 +422.03 +888.55 +534.11 +0.052916 +2180.4 +554.26 +218.29 +663.52 +1142.7 +817.44 +181.83 +0.089715 +0.032828 +947.58 +770.61 +1104.5 +1372.5 +678.25 +0.03667 +2659.3 +4856.2 +108.41 +123.03 +385.33 +379.59 +289.76 +250.33 +44.122 +260.79 +406.53 +1078.2 +3163.8 +273.69 +143.51 +168.7 +161.71 +171.2 +83.715 +82.244 +82.581 +57.142 +84.223 +0.058064 +0.018525 +0.39208 +0.15717 +16.971 +26.239 +52.178 +14.793 +118.26 +87.222 +61.228 +19.653 +30.895 +16.039 +13.371 +0.076717 +0.042508 +0.14078 +368.6 +666.25 +390.75 +501.48 +1717.7 +227.22 +241.15 +1341.2 +2700.1 +1806.7 +0.19326 +0.62515 +0.083615 +0.068975 +1131.9 +1615.2 +1545.7 +2075.8 +2324 +0.1476 +6878.3 +90.707 +312.39 +208.75 +242.32 +233.34 +151.02 +500.75 +388.44 +272.79 +1254.3 +4917.3 +98.984 +180.57 +198.4 +57.886 +259.46 +261.01 +67.35 +39.523 +42.377 +68.401 +157.25 +0.01787 +0.093927 +180.75 +30.16 +22.477 +30.127 +17.203 +136.04 +33.182 +39.505 +30.61 +43.289 +28.315 +12.101 +0.051425 +0.11961 +0.062837 +404.75 +513.94 +507.17 +864.34 +545.76 +211.6 +321.55 +1383.1 +0.083571 +0.14291 +0.054787 +0.060374 +0.078012 +0.13783 +0.18706 +0.033564 +1573.2 +1813.8 +1907 +165.69 +81.013 +34.524 +163.51 +116.98 +94.782 +221.14 +1203.7 +794.01 +199.88 +328.06 +84.876 +134.85 +307.53 +117.17 +91.555 +149.31 +160.97 +256.08 +534.92 +40.635 +52.465 +52.969 +97.493 +0.016214 +0.036701 +234.14 +24.63 +58.414 +40.832 +18.311 +128.47 +33.194 +52.25 +12.694 +16.668 +32.631 +0.067626 +0.070366 +0.044752 +0.034006 +0.027681 +658.06 +758.61 +390 +426.88 +510.17 +464.74 +0.13617 +0.061527 +0.087851 +0.020834 +0.045807 +0.4487 +0.084579 +0.11244 +0.15476 +0.15494 +419.6 +284.29 +119.32 +93.848 +84.025 +223.19 +177.65 +6307.8 +507.65 +3118.7 +911.39 +391.22 +679.23 +100.11 +126.79 +283.41 +173.7 +113.68 +225.72 +131.52 +225.97 +817.71 +348.18 +372.26 +57.65 +90.304 +20.171 +516.09 +247.33 +63.356 +74.041 +24.325 +8.2242 +58.143 +22.833 +78.461 +18.696 +40.656 +28.866 +93.915 +0.011003 +0.073427 +4526 +10336 +494.75 +304.54 +1025 +237.63 +0.002272 +0.005741 +0.060402 +0.14137 +0.20482 +0.10709 +0.083907 +0.0853 +0.10609 +0.037686 +0.067858 +318.77 +273.43 +400.58 +150.08 +411.98 +51.441 +409.36 +565.16 +1434.6 +299.26 +2137.7 +734.81 +324.33 +967.01 +102.8 +120.28 +180.99 +0.086837 +0.033348 +0.008534 +96.816 +193.99 +313.71 +956.59 +718.23 +850.96 +178.73 +0.1603 +910.03 +183.92 +98.902 +80.227 +24.142 +0.020188 +23.907 +14.608 +28.496 +29.781 +22.497 +77.264 +159.32 +1591.7 +2224.3 +2747.5 +7564.6 +412.89 +493.36 +502.46 +0.012131 +0.008558 +0.026392 +0.085925 +0.1077 +0.071627 +0.094142 +0.046302 +0.048062 +0.034325 +0.21603 +300.71 +177.25 +211.43 +427.51 +146.06 +442.42 +975.6 +335.97 +967.08 +2985.5 +60.42 +54.068 +704.03 +0.02306 +1035.3 +176.47 +127.3 +0.019727 +0.29127 +0.068753 +0.027058 +2487.6 +104.35 +292.43 +1463 +259.57 +170.55 +0.15116 +492.86 +539.76 +457.75 +102.31 +55.297 +38.528 +6.612 +15.844 +7.7647 +14.473 +10.46 +17.294 +8942.5 +4122.4 +594.54 +802.4 +3440.1 +146.86 +126.7 +511.74 +601.7 +0.057692 +0.012538 +0.01099 +0.038868 +0.044684 +0.13979 +0.030668 +0.21989 +0.13407 +0.11574 +0.2496 +199.53 +114.29 +274.94 +33.134 +479.09 +450.39 +982.35 +304.81 +88.049 +209.88 +55.653 +31.25 +113.94 +445.04 +946.55 +151.36 +174.95 +0.049855 +0.13605 +226.8 +34.862 +738.82 +50.615 +1907.3 +996.84 +465.19 +85.041 +276.28 +181.44 +655.15 +919.45 +109.43 +37.833 +27.835 +6.7402 +15.373 +8.2221 +7.6279 +1380.1 +533.43 +194.9 +5635.1 +274.6 +235.42 +62.942 +78.698 +69.16 +0.007722 +0.13023 +0.049211 +0.010245 +0.020563 +0.022641 +0.091124 +0.15535 +0.19873 +0.29305 +0.33786 +0.10192 +0.042678 +0.020192 +23.556 +14.152 +45.576 +307.51 +136.5 +624.89 +858.12 +99.928 +151.83 +71.425 +25.967 +56.879 +472.13 +510.66 +352.05 +79.415 +0.17203 +218.25 +75.95 +56.997 +497.52 +27.933 +270.4 +669.57 +303.85 +105.2 +228.22 +122.79 +637.57 +303.92 +374.63 +245.07 +502.21 +680.14 +1623.2 +8.4624 +8.9577 +629.67 +0.061892 +8909.8 +159.49 +677.37 +153.96 +85.477 +45.226 +60.335 +0.10648 +0.18655 +0.22092 +0.012167 +0.030462 +0.015229 +0.028981 +0.048712 +0.43826 +0.252 +1.0217 +0.018653 +0.036854 +73.349 +16.855 +11.295 +26.129 +347.36 +322.43 +552.6 +890.92 +32.549 +43.508 +73.622 +24.926 +109.28 +238.14 +416.98 +188.04 +449.95 +398.66 +170.41 +79.815 +95.673 +0.27222 +0.18093 +0.099412 +728.63 +279.76 +106.08 +105.93 +114.35 +579.9 +145.47 +350.57 +326.93 +327.06 +404.72 +2442.8 +23.22 +0.13094 +1272.3 +0.061405 +948.63 +670.77 +125.22 +195.95 +34.767 +4.7996 +7.6113 +206.15 +20000 +0.085704 +0.024358 +0.058225 +0.026277 +0.12056 +0.12881 +0.095422 +0.20475 +0.1025 +261.33 +28.282 +79.353 +11.461 +14.806 +46.148 +381.07 +1339.5 +2644.2 +2204 +18499 +13.498 +49.602 +49.291 +104.11 +170.35 +330.54 +179.27 +468.26 +248.86 +294.03 +0.053086 +0.15638 +0.17896 +0.057096 +0.10409 +389.8 +278.98 +138.09 +251.28 +69.998 +487.99 +193.42 +498.54 +583.57 +304.76 +441.69 +795.82 +28.704 +4453.1 +309.73 +218.23 +598.49 +126.07 +191.18 +238.11 +151.22 +4.2604 +16.769 +8.6944 +46.896 +20000 +0.058789 +0.031753 +0.029668 +0.052241 +0.060219 +0.055602 +0.042411 +116.59 +141.78 +33.119 +49.46 +18.537 +107.1 +109.59 +453.53 +856.03 +1966.7 +4702.7 +10483 +21.285 +36.398 +48.881 +57.389 +1738.9 +540.17 +227.33 +630.35 +183.45 +226.62 +0.036326 +0.18052 +0.26416 +0.062086 +165.83 +545.48 +363.39 +98.071 +236.69 +114.21 +793.05 +477.92 +441.84 +267.67 +241.48 +472.05 +22.592 +0.35364 +141.98 +228.99 +224.72 +725.45 +82.94 +194.02 +189.35 +233.12 +489.4 +156.65 +8.6617 +132.28 +274.97 +169.6 +0.050915 +0.20541 +0.15962 +0.040473 +0.075542 +0.018255 +62.153 +123.03 +46.883 +42.171 +5631.1 +156.32 +66.638 +398.24 +674.13 +1072.3 +3557.2 +19321 +39.996 +28.732 +1360 +1106.8 +2210.8 +110.59 +66.505 +42.229 +200.82 +373.87 +595.05 +172.14 +279.86 +89.853 +139.81 +406.56 +220.54 +68.397 +113.36 +94.087 +1111.3 +324.35 +731.92 +95.594 +266.7 +62.053 +0.34574 +0.2113 +210.22 +337.77 +166.75 +9545.1 +62.981 +276.98 +349.55 +394.66 +634.95 +108.46 +0.13416 +107.17 +152.83 +338.19 +364.16 +519.42 +0.07794 +0.033883 +0.2838 +0.19881 +69.799 +49.651 +25.233 +25.888 +114.23 +52.859 +129.04 +423.46 +474.19 +1418.7 +2605 +14113 +6876.4 +632.08 +0.092299 +0.14075 +31.368 +110.51 +51.841 +23.413 +70.669 +550.1 +466.24 +118.63 +261.82 +77.011 +244.97 +433.74 +323.13 +397.83 +86.997 +482.12 +739.15 +143.05 +334.83 +0.10281 +0.22904 +0.15238 +0.022898 +0.097099 +205.89 +566.19 +99.629 +183.24 +74.231 +489.25 +531.23 +396.59 +1122 +528.96 +0.051827 +0.083037 +229.91 +319.65 +531.87 +430.27 +732.83 +7.0731 +0.06587 +0.10876 +75.451 +58.959 +30.712 +16.583 +50.468 +59.804 +154.15 +251.82 +468.08 +1276.3 +1122.8 +8582.5 +10320 +3300.7 +0.15433 +0.20388 +0.63893 +0.18157 +52.929 +24.673 +545.4 +274.18 +278.55 +75.689 +116.33 +162.69 +268.68 +551.12 +0.19239 +0.11292 +60.657 +434.49 +979.98 +21.284 +19.879 +0.099067 +0.27608 +0.11631 +0.30046 +211.34 +202.58 +258.79 +45.264 +203.56 +153.83 +614.78 +936.77 +935.1 +979.13 +0.42986 +0.23606 +0.2249 +0.40697 +369.44 +514.15 +197.64 +180.6 +21.749 +27.009 +17.92 +57.311 +21.804 +23.169 +30.378 +162.28 +143.9 +313.23 +379.54 +711.43 +1728.3 +1246.5 +3557.4 +14315 +4393.6 +0.045182 +0.10496 +141.78 +220.48 +98.791 +352.79 +813.81 +261.83 +233.61 +31.084 +0.065815 +0.16378 +0.2224 +0.20522 +0.23151 +110.96 +75.017 +0.053733 +34.637 +34.584 +25.741 +0.060038 +0.47984 +0.18324 +0.17818 +0.14935 +440.01 +144.25 +90.102 +7591.9 +2420.2 +469.07 +994.25 +256.92 +386.32 +0.4726 +0.2206 +0.10404 +0.25653 +0.21994 +491.04 +171.67 +449.13 +171.95 +14.905 +15.409 +51.898 +18.941 +8.0037 +46.097 +219.13 +210.1 +455.97 +220.09 +0.032572 +1991.2 +1630.7 +7786.8 +20000 +10464 +9506.7 +476.34 +323.28 +125.83 +109.16 +214.58 +521.41 +157.49 +281.17 +7353.2 +0.028334 +0.12307 +0.049167 +0.050323 +0.060093 +0.085251 +0.10346 +0.03905 +0.060784 +68.62 +48.841 +51.48 +55.646 +172.46 +435.81 +564.81 +238.47 +253.22 +55.839 +106.42 +213.26 +1892.6 +1061.9 +427.01 +275.19 +231.97 +0.66456 +0.14827 +0.26272 +0.10371 +0.2377 +165.92 +156.79 +154.46 +16.875 +23.637 +77.109 +27.485 +6.6853 +80.203 +161.46 +342.98 +45.325 +85.355 +0.10149 +634.3 +1968.6 +9329.9 +10999 +2855.7 +11456 +400.77 +1128.2 +70.43 +0.16392 +576.76 +1125.1 +135.97 +191.64 +4497.4 +1402.9 +0.13357 +0.064486 +0.065728 +0.069227 +0.02709 +0.077618 +0.035601 +0.026241 +0.069374 +52.44 +156.85 +15.385 +265.81 +707.69 +1896.8 +1876.6 +122.75 +48.43 +326.29 +163.61 +0.24287 +0.48659 +536.6 +517.08 +269.23 +0.18578 +0.16186 +0.2275 +0.065137 +0.36187 +0.13932 +358.77 +340.26 +505.36 +81.75 +82.705 +20.117 +19.797 +157.64 +279.37 +142.96 +44.14 +0.15828 +922.11 +755.57 +922.31 +14702 +13445 +1706 +12244 +15940 +0.073185 +0.22957 +49.04 +447.54 +320.07 +116.87 +261.78 +938.64 +1081.3 +0.20777 +0.12221 +0.18277 +0.10492 +0.029754 +0.093913 +0.27934 +0.080188 +0.12469 +37.618 +60.276 +80.551 +101.44 +47.278 +1058.1 +3053.7 +121.17 +76.871 +195.09 +107.5 +122.78 +0.30328 +0.68965 +501.64 +134.37 +53.823 +0.09565 +0.018662 +0.11248 +0.063694 +0.29031 +421.38 +525.67 +399.43 +160.19 +45.561 +30.058 +20.207 +189.46 +259.87 +159.38 +330.54 +120.43 +1131.4 +535.07 +998.61 +18824 +11549 +2342.9 +10327 +11622 +20000 +100.18 +138.46 +174.17 +197.57 +131.49 +35.636 +859.09 +755.13 +0.12208 +0.06326 +0.17272 +0.16701 +0.074919 +0.28059 +0.097066 +78.622 +28.389 +51.072 +35.034 +59.461 +19.288 +103.09 +88.101 +4344.6 +0.082997 +47.989 +543.78 +182.17 +222.24 +0.20307 +0.33123 +1.1954 +125.88 +187.31 +245.27 +0.074553 +0.080342 +0.14937 +0.060376 +551.16 +343.73 +552.14 +154.86 +81.622 +28.188 +19.149 +114.79 +167.95 +55.014 +100.81 +281 +570.48 +246.54 +913.15 +902.89 +0.28008 +2308.8 +8697 +18408 +19984 +16036 +222.52 +74.515 +92.665 +69.826 +45.865 +967.5 +0.10053 +0.047957 +0.2536 +0.31526 +0.48919 +0.14268 +0.61258 +29.592 +170.92 +58.489 +98.876 +15.002 +67.972 +273.48 +109.28 +72.592 +36.251 +0.20465 +0.073255 +416.49 +355.74 +330.01 +108.41 +0.31262 +0.24472 +0.50086 +289.54 +305.19 +392.76 +0.046269 +1364.5 +1327.8 +1237.5 +328.25 +443.09 +198.19 +75.954 +30.309 +25.599 +141.79 +96.878 +75.471 +46.122 +16.209 +462.37 +171.34 +1103 +60.938 +0.18159 +2799.2 +5734.3 +20000 +8483 +14129 +3510.5 +55.485 +114.45 +137.68 +23.673 +0.14777 +0.070849 +0.1263 +0.16507 +0.12828 +0.10689 +0.08366 +0.41969 +12.148 +350.06 +102.6 +137.85 +25.573 +116.32 +917.42 +474.11 +87.351 +35.026 +0.024031 +0.077738 +419.87 +456.46 +370.93 +198.7 +0.20856 +0.20605 +0.37574 +0.24119 +0.12551 +304.4 +380.06 +66.674 +71.871 +80.959 +154.45 +174.2 +120.15 +112.93 +30.151 +849.27 +883.1 +68.032 +39.522 +21.946 +16.395 +60.955 +114.05 +474.19 +33.016 +9.7092 +2993.5 +3237.1 +11553 +8108.9 +6792.4 +6191.8 +39.122 +101.54 +193.04 +0.036409 +0.24783 +0.39837 +0.050049 +0.13898 +0.071489 +0.15832 +0.12409 +0.024948 +0.02717 +452.57 +94.975 +125.14 +183.78 +212.71 +459.83 +1083.7 +783.08 +31.626 +34.915 +1104.8 +846.78 +587.09 +493.19 +353.47 +295.52 +329.9 +501.04 +218.75 +63.826 +235.55 +39.531 +76.067 +102.75 +0.025146 +0.081144 +0.033627 +0.017223 +181.02 +15.509 +173.78 +389.62 +396.68 +613.92 +28.719 +23.036 +46.045 +77.145 +85.617 +42.264 +13.291 +29.488 +2690.1 +10504 +10224 +6468.9 +7848.9 +5778.2 +116.14 +255.67 +0.046071 +0.23661 +0.23892 +0.26159 +0.36131 +0.015283 +0.18383 +0.047899 +0.03856 +0.032439 +0.27664 +109.79 +172.77 +168.4 +113.13 +24.335 +173.53 +48.974 +48.538 +2315.7 +1026.2 +840.83 +551.05 +313.03 +249.76 +344.58 +307.28 +135.96 +177.99 +428.03 +0.043837 +0.41669 +2624.1 +762.69 +727.96 +0.046257 +0.14633 +0.075508 +182.56 +34.696 +96.186 +131.53 +420.43 +1467 +143.31 +8.5592 +50.311 +47.216 +43.768 +240.3 +107.82 +29.467 +1813.8 +3962 +8994.7 +5268.8 +7004.7 +3779.8 +78.952 +246.37 +0.12059 +0.075028 +0.15795 +0.15238 +0.27144 +0.098843 +0.0699 +0.213 +0.15767 +0.381 +0.60497 +799.89 +107.68 +99.013 +71.833 +75.325 +206.53 +37.644 +38.616 +1900.7 +609.88 +637.64 +918.04 +90.394 +481.77 +221.92 +187.56 +0.2294 +0.46302 +0.06562 +0.031653 +267.83 +1186.8 +795.53 +370.82 +0.077734 +0.03083 +0.043048 +174.83 +54.818 +52.029 +76.192 +188.3 +319.68 +120.25 +238.01 +191.25 +38.755 +158.48 +135.68 +181.29 +406.91 +282.7 +3311.4 +4814.6 +3585.9 +7761.7 +3881.2 +846.31 +0.086949 +0.10202 +0.052249 +0.28253 +0.10332 +0.18271 +0.10702 +0.17144 +0.55987 +0.15518 +2.0496 +73.8 +133.71 +126.26 +155.91 +94.883 +90.031 +119.32 +35.375 +1227.9 +2271.3 +550.51 +98.403 +85.911 +83.981 +0.29934 +0.13344 +0.14333 +0.077316 +0.12509 +0.064666 +0.10513 +274.43 +1265.3 +983.17 +0.051347 +0.018314 +0.091159 +0.019621 +0.099907 +1.0825 +51.356 +86.534 +100.99 +312.72 +532.08 +391.66 +228.79 +34.181 +125.81 +298.69 +437 +689.64 +354.82 +5237.1 +11255 +3628.4 +9770.9 +5856.3 +1778.5 +0.13399 +0.023454 +0.087332 +0.037313 +0.15404 +0.048491 +0.052891 +0.061447 +0.22213 +43.282 +67.874 +116.76 +72.129 +54.182 +63.863 +122.55 +162.21 +81.504 +20.63 +33.49 +4785.4 +1832.1 +6520.8 +162.25 +91.154 +0.14583 +0.15027 +0.08683 +0.023238 +0.020849 +0.46043 +229.6 +379.55 +811.65 +1626.5 +0.039916 +0.012936 +0.13504 +0.0431 +0.60974 +0.46007 +0.064702 +82.252 +143.08 +632.33 +501.52 +488.26 +270.64 +7.6214 +90.725 +125.28 +936.31 +763.32 +624.63 +549.46 +2602.5 +1461.7 +9422.5 +11755 +3087.1 +4066.4 +0.082078 +0.061463 +0.035707 +0.44105 +0.053522 +0.089714 +0.039575 +55.468 +28.521 +117.1 +203.69 +202.94 +147.25 +157.56 +380.54 +108.5 +97.104 +163.15 +92.388 +4457.4 +5335.4 +6532.4 +5788 +0.33996 +0.45049 +0.49725 +0.20038 +0.42904 +0.071308 +267.39 +164.13 +488 +701.77 +0.085081 +0.044189 +0.026306 +0.11488 +0.20757 +201.13 +0.10324 +0.020678 +0.20478 +184.35 +605.83 +519.96 +460.74 +485.89 +622.06 +422.35 +159.38 +3313.4 +352.9 +935.27 +1279.9 +1473.4 +2156.4 +1300.5 +4967.8 +3252.6 +4246.7 +1252.4 +0.052149 +0.3079 +67.434 +75.049 +320.34 +58.434 +99.523 +57.999 +137.92 +65.159 +153.36 +541.38 +209.39 +357.34 +110.93 +129.27 +142.69 +93.651 +312.27 +10347 +11399 +9693.4 +2540.1 +0.19946 +0.38728 +38.135 +139.72 +527.38 +305.19 +194.73 +582.86 +0.25537 +0.45171 +0.29298 +0.13606 +0.069507 +0.096938 +127.4 +0.067033 +0.08114 +0.072745 +234.64 +921.34 +671.36 +259.89 +613.15 +535.76 +325.93 +2210.8 +3704.4 +64.302 +3399.2 +1954.2 +1198 +1236.4 +771.21 +907.98 +118.77 +60.177 +57.668 +57.181 +166.76 +132.06 +128.17 +430.11 +83.075 +664.71 +189.25 +93.583 +33.572 +17.382 +27.138 +0.15643 +98.319 +58.568 +139.78 +145.37 +214.59 +202.92 +11568 +9209.5 +56.101 +33.927 +21.344 +216.71 +84.914 +151.41 +591.12 +0.034204 +0.042723 +0.12519 +0.26055 +0.041349 +0.62342 +0.31893 +0.017328 +0.18152 +87.708 +0.11709 +0.12679 +0.065251 +427.03 +132.26 +658.26 +406.39 +608.25 +237.26 +148.45 +609.6 +120.12 +54.01 +7079.5 +6846.2 +1047.2 +1231.4 +518.96 +17.765 +16.125 +71.669 +33.905 +38.618 +111.37 +40.705 +0.24985 +528.05 +309.16 +360.2 +331.01 +77.411 +41.965 +0.31075 +0.31499 +0.63556 +46.76 +90.775 +71.922 +166.56 +211.69 +647.67 +158.57 +67.439 +47 +33.179 +54.502 +132.33 +217.83 +0.33456 +0.4556 +0.16832 +0.039423 +0.01732 +0.031499 +0.14294 +0.30992 +0.082471 +0.061064 +0.086414 +161.11 +0.24199 +94.826 +7.5736 +160.47 +46.843 +62.732 +248.94 +255.64 +145.1 +167.18 +1431.5 +96.352 +188.22 +151.82 +7009.8 +955.22 +23.798 +5.8709 +15.955 +67.27 +61.509 +173.23 +3467.1 +3358.1 +340.26 +0.1087 +175.6 +347.31 +409.32 +181.72 +0.020412 +0.43702 +0.23997 +0.19749 +1087.6 +739.29 +258.94 +114.74 +175.14 +24.965 +590.07 +191.2 +160.37 +119.23 +56.37 +48.726 +2694.9 +0.17876 +0.29649 +0.27614 +0.11797 +0.041392 +0.029639 +0.059356 +0.43379 +0.2951 +0.06078 +0.073678 +0.09094 +110.14 +0.032875 +72.236 +12.499 +119.4 +43.02 +1212.4 +197.09 +91.781 +66.608 +165.16 +571.38 +189.41 +87.048 +12131 +8930.2 +544.84 +16.451 +7.6139 +10.072 +385.99 +414.53 +331.22 +2722.3 +3730.4 +726.2 +0.066391 +293.48 +319.4 +286.56 +198.93 +0.21951 +0.30589 +0.22702 +0.35649 +1128.2 +1270.1 +795.65 +621.67 +245.36 +55.523 +45.343 +242.87 +102.26 +135.57 +95.17 +1105.7 +3243.5 +2443.7 +0.12618 +0.039646 +0.092272 +0.019015 +0.049392 +0.13788 +0.29458 +0.38693 +0.11744 +0.14648 +0.10673 +0.0909 +0.14405 +0.052876 +16.981 +29.422 +19.697 +266.75 +251.86 +135.32 +39.383 +235.9 +391.03 +130.08 +15.036 +17.366 +5406.4 +664.88 +900.34 +3.0586 +6.2398 +37.197 +454.16 +386.48 +3780.2 +3191.3 +0.064868 +0.12711 +314.4 +489.83 +754.37 +498.65 +0.036711 +0.16258 +0.17232 +0.18831 +2229.8 +1412.8 +1410.5 +324.31 +231.47 +34.193 +13.419 +9.1415 +12.812 +195.79 +107.12 +133.26 +1748.8 +906.83 +0.19532 +0.23695 +0.314 +0.1709 +0.14633 +0.20825 +0.15526 +0.29746 +0.32529 +0.072272 +0.089327 +260.09 +0.063145 +93.052 +9.6554 +25.427 +17.852 +221.4 +194.89 +172.49 +30.199 +249.35 +379.56 +763.34 +186.2 +26.149 +3026.2 +692.78 +723.21 +315.18 +3.0772 +21.304 +393.17 +246.61 +4271.9 +0.060919 +0.046626 +0.029377 +654.32 +333.56 +1338.4 +1098.4 +0.11303 +0.90226 +1.3895 +3366.2 +2411.3 +1054.4 +1000.3 +277.56 +153.2 +34.629 +30.943 +14.62 +13.599 +36.955 +70.606 +88.729 +47.73 +907.49 +1619.4 +0.069392 +0.053491 +0.2081 +0.082038 +0.31546 +0.16645 +0.18893 +0.97556 +0.13254 +0.043768 +733.47 +547.99 +161.23 +50.288 +9.3552 +53.824 +154.03 +75.496 +102.25 +55.905 +433.64 +933.58 +852.92 +32.672 +852.94 +421.81 +685.36 +602.51 +314.85 +109.95 +26.05 +3.2997 +357.36 +0.053596 +0.053042 +0.056365 +0.071051 +0.059369 +290.48 +1081.4 +1135.5 +0.3802 +203.72 +297.87 +2148.7 +1160.7 +1972.9 +698.74 +42.374 +52.705 +18.381 +15.618 +12.723 +11.885 +25.529 +41.156 +111.99 +45.488 +1386.9 +1187.6 +0.085396 +0.22767 +0.079375 +0.41602 +0.45795 +0.13486 +0.23069 +0.17411 +0.073808 +0.039912 +951.34 +180.92 +42.837 +44.92 +13.294 +44.696 +74.187 +30.373 +92.036 +28.542 +486.42 +447.17 +1746.4 +3610.7 +1197.2 +244.98 +480.04 +1316 +438.55 +148.34 +127.92 +2.4026 +4.301 +7.3373 +5.1145 +0.1194 +0.23882 +0.054546 +520.7 +1099.1 +3755.4 +2360.6 +1544.9 +334.44 +2940.2 +2360.2 +1715.7 +88.508 +98.399 +69.571 +27.698 +21.688 +16.703 +11.3 +13.157 +60.59 +41.459 +59.17 +2544.4 +842.38 +1049.9 +0.31323 +0.55603 +0.10551 +0.29991 +0.024167 +0.016651 +0.052495 +0.094912 +0.18037 +191.82 +158.57 +122.34 +66.923 +21.741 +68.479 +112.96 +876.82 +582.08 +982.02 +538.5 +5203.7 +2959.4 +3914.2 +501.39 +293.79 +870.55 +2222.3 +619.4 +1147.8 +327.87 +258.82 +4.7098 +1.8105 +8.2864 +3.3241 +0.15997 +0.33156 +0.20342 +1462.9 +4944.5 +5239 +1275.5 +214.71 +1638.8 +5050.7 +1614.2 +84.125 +94.556 +44.072 +15.984 +36.715 +27.435 +6.5033 +10.267 +91.466 +59.405 +968.65 +2216.9 +832.26 +1054.5 +651.58 +0.19969 +0.18527 +0.054305 +0.10823 +0.037332 +0.027316 +0.082641 +0.13353 +290.28 +417.81 +91.493 +93.026 +23.152 +73.085 +1171.5 +583.13 +554.53 +5963.4 +4200.4 +2515.3 +6321 +4449.1 +1047.5 +460.64 +1966.2 +683.61 +555.77 +1028.4 +280.78 +244.74 +510.85 +3.254 +4.3246 +7.8743 +5.6469 +186.84 +678.8 +1366.3 +3388.3 +2437.8 +1217.1 +1138.4 +1947.5 +5538.5 +111.19 +78.119 +65.127 +36.123 +14.116 +13.35 +11.48 +4.6086 +12.245 +24.563 +1434.5 +407.44 +762.2 +469.99 +616.19 +488.6 +0.17245 +0.13277 +0.068116 +0.53689 +0.080141 +0.21701 +0.064639 +0.43209 +205.5 +292.56 +141.74 +144.65 +52.802 +147.63 +2286.2 +1123.9 +1103.6 +1604.4 +5023.1 +2617.7 +3409.5 +7741.7 +818.84 +1323.4 +3132.8 +731.03 +394.11 +619.52 +552.56 +455.54 +631.72 +0.39564 +0.26183 +16.051 +19.122 +117.11 +200.16 +943.09 +4720.9 +1936.3 +1225 +633.51 +11.427 +18.259 +99.629 +28.145 +46.964 +28.572 +8.9142 +15.233 +5.3705 +3.1412 +6.8421 +0.037312 +4069.8 +697.2 +460.84 +347.69 +639.37 +304.68 +0.10547 +0.27055 +0.11715 +52.078 +0.041982 +0.2702 +0.059777 +0.13009 +408.22 +550.12 +296.14 +289.4 +115.23 +179.51 +876.69 +767.14 +2202.2 +2010.4 +5082.8 +3432 +2299 +2044 +573.66 +335.86 +1015.9 +444.93 +442.93 +519.13 +200.91 +234.86 +1166.4 +0.10979 +134.56 +118.02 +33.468 +10.456 +16.116 +93.107 +211.61 +908.18 +1614 +542.83 +18.869 +18.769 +61.91 +25.595 +33.321 +32.171 +7.3741 +4.9261 +3.7732 +7.7995 +0.15224 +0.049007 +0.21298 +743.64 +716.26 +234.54 +281.05 +320.82 +0.079058 +0.049581 +0.056477 +0.058339 +121.73 +88.976 +142.79 +0.084129 +358.96 +714.44 +473.74 +495.39 +111.94 +214.81 +1482.5 +1608.2 +1560.5 +996.76 +5466.6 +7466.3 +860.15 +34.31 +76.165 +376.09 +940.98 +648.1 +259.02 +343.05 +237.32 +429.58 +1284.2 +0.35656 +203.06 +92.915 +38.74 +1952.8 +57.5 +16.034 +15.171 +144.9 +146.6 +386.64 +13.552 +25.337 +49.745 +9.3368 +32.106 +21.814 +10.057 +8.3833 +3.4628 +0.31986 +0.44443 +0.031781 +0.24833 +483.19 +701.32 +354.28 +192.43 +209.7 +237.15 +0.036185 +0.10056 +0.071706 +266.71 +84.15 +90.284 +325.55 +730.94 +663.1 +561.57 +391.81 +90.439 +0.015546 +3261.2 +1657.2 +1785 +1281 +4926.5 +7388 +189.66 +47.789 +111.6 +385.84 +826.85 +733.14 +770.03 +1389.6 +720.64 +942.37 +0.094865 +0.34804 +361.38 +44.217 +52.052 +55.382 +55.763 +135.04 +11.165 +46.845 +155.18 +84.62 +14.106 +27.621 +30.876 +32.422 +23.38 +6.5055 +5.5295 +0.032178 +0.067851 +0.92011 +0.10991 +0.35937 +0.36764 +253.72 +204.32 +261.34 +132.96 +121.03 +164.39 +0.063615 +0.30102 +0.039288 +0.060661 +287.73 +130.21 +315.86 +1012.5 +406.59 +967.14 +466.26 +67.718 +415.6 +2500.3 +1952.1 +1514.4 +1331 +6187.9 +37.46 +122.8 +65.286 +64.479 +572.95 +525.35 +587.39 +974.17 +3823.8 +458.61 +83.664 +0.13177 +71.58 +270.96 +48.323 +97.772 +60.059 +43.288 +170.48 +688.02 +166.21 +234.4 +103.27 +29.945 +115.2 +54.189 +21.057 +11.543 +6.9722 +0.054221 +0.036881 +0.20741 +0.12757 +0.082005 +0.20037 +0.19051 +265.27 +347.57 +478.71 +145.93 +106.95 +125.97 +180.21 +0.37074 +0.3512 +0.11881 +782.51 +118.94 +190.28 +2246.3 +1446.3 +1310.1 +643.15 +392.78 +473.62 +2065.7 +3092.9 +848.06 +1078 +3044.3 +39.578 +89.87 +103.36 +113.57 +782.41 +953.63 +143.16 +711.19 +102.85 +89.746 +94.361 +0.020802 +83.937 +109.24 +71.171 +89.005 +68.735 +85.852 +93.225 +338.5 +219.85 +119.01 +151.15 +49.583 +128.24 +235.5 +13.677 +3.9162 +3.4719 +0.036448 +0.016638 +0.10974 +0.025776 +0.17872 +0.051307 +409.19 +214.74 +170.31 +171.8 +178.89 +99.285 +121.7 +3.25 +0.46682 +0.27197 +0.038411 +0.11383 +220.85 +128.53 +3456.6 +2369.7 +133.38 +904.17 +868.23 +1260.2 +3292.2 +1504.7 +1165.8 +2589.1 +4327.9 +46.512 +130.75 +174.84 +127.76 +783.3 +287.67 +235.85 +575.19 +61.65 +104.44 +92.054 +78.274 +65.097 +20.35 +103.39 +81.509 +50.337 +45.021 +251.01 +142.09 +960.98 +161.4 +161.57 +97.999 +185.49 +176.66 +20.015 +6.2954 +525.24 +68.706 +0.22691 +0.066399 +0.057007 +46.673 +116.12 +534.63 +442.88 +392.69 +179.41 +152.85 +65.772 +0.095101 +0.25768 +0.033214 +0.17778 +0.014181 +0.060031 +0.16431 +20.129 +3236 +61.693 +343.21 +965.7 +834.12 +713 +3136.9 +2154.5 +1684.5 +2235.7 +190.79 +21.416 +97.067 +145.73 +297.62 +128.56 +168.29 +224.18 +70.085 +1201.3 +302.88 +240.3 +108.07 +61.823 +32.249 +85.159 +39.965 +388.2 +319.55 +413.41 +224.91 +768.18 +245.77 +665.64 +62.988 +148.35 +125.86 +154.12 +233.24 +447.69 +79.678 +58.148 +0.12035 +153.03 +70.147 +138.95 +338.78 +339.17 +206.98 +95.374 +119.32 +0.061426 +0.084487 +1.1804 +0.29996 +0.019248 +0.026253 +0.027998 +62.864 +24.047 +21.726 +64.381 +207.61 +189.7 +563.36 +1214.8 +3294.3 +1658 +2824.1 +86.644 +145.2 +27.612 +70.64 +106.62 +28.807 +43.086 +56.782 +3162.7 +1376.1 +1386.1 +118.63 +250.56 +156.23 +176.66 +544.03 +159.88 +146.33 +898.93 +198.91 +447.5 +353.27 +627.32 +341.92 +63.292 +68.802 +153.75 +153.29 +185.97 +153.71 +524.92 +416.46 +259.45 +0.027143 +393.46 +96.603 +59.025 +147.99 +236.23 +234.55 +165.65 +0.41817 +0.10333 +0.11642 +0.069868 +0.13281 +0.10186 +0.060185 +45.732 +60.076 +21.233 +36.585 +48.326 +130.62 +189.66 +845.24 +780.01 +1908.3 +208.62 +167.75 +90.478 +60.41 +897.06 +263.36 +56.516 +39.65 +705.76 +1966.9 +1397.9 +1315.7 +1115.8 +623.37 +232.61 +146.36 +385.61 +197.86 +159.9 +90.327 +653.81 +279.15 +440.25 +150.54 +324.71 +188.91 +131.97 +138.71 +76.791 +179.92 +60.628 +27.495 +40.028 +105.76 +26.723 +738.87 +414.74 +56.036 +114.41 +123.45 +194.09 +91.101 +184.3 +0.25979 +0.019588 +0.099334 +0.21981 +0.099103 +0.024215 +0.088715 +66.723 +103.2 +17.681 +42.349 +69.797 +190.81 +288.01 +990.07 +1043.5 +48.275 +12.072 +288.3 +50.763 +810.42 +31.41 +80.397 +28.468 +92.216 +466.96 +2019.2 +997.98 +1088.8 +812.79 +417.17 +180.77 +56.066 +159.04 +222.37 +176.28 +105.5 +1115.1 +344.83 +330.7 +106.94 +297.76 +186.75 +343.78 +343.12 +58.288 +246.61 +104.77 +40.482 +25.593 +60.988 +28.976 +317.12 +900.53 +110.85 +165.11 +295.52 +160.01 +109.18 +212.56 +0.22673 +0.047076 +0.056549 +0.27241 +0.14521 +0.039006 +34.946 +119.14 +68.839 +20.158 +26.525 +109.2 +84.181 +180.95 +107.23 +26.654 +41.926 +12.439 +20.542 +0.62664 +91.266 +60.013 +48.837 +26.944 +85.27 +844 +2678.3 +1574.1 +1237.7 +334.01 +461.17 +235.47 +113.44 +91.406 +191.4 +115.61 +125.97 +1193.8 +740.37 +286.37 +91.103 +542.14 +232.26 +539.56 +112.08 +120.87 +212.24 +85.426 +91.637 +32.967 +99.588 +12.455 +10.973 +407.4 +175.17 +286.11 +312.26 +355.07 +150.02 +238.14 +0.034484 +0.013058 +0.0192 +0.10105 +68.43 +53.583 +72.121 +68.19 +55.213 +30.108 +36.227 +171.6 +157.41 +3075.8 +964.19 +27.825 +68.663 +12.995 +10.282 +12.274 +172.28 +36.891 +87.62 +26.678 +637.13 +1510.6 +3177.3 +1644.3 +1406.2 +517.34 +507.96 +400.61 +200.69 +180.53 +73.393 +193.07 +173.73 +1250.9 +796.15 +576.58 +515.23 +259.83 +344.4 +481.8 +159.91 +74.569 +124.6 +74.994 +106.75 +22.688 +176.46 +12.388 +502.16 +349.64 +2976.5 +331.75 +333.69 +328.73 +182.37 +191.19 +743.18 +755.27 +0.03503 +0.10898 +29.441 +35.312 +35.826 +111 +70.684 +72.816 +55.644 +58.629 +101.67 +2471.6 +860.18 +766.9 +883.26 +25.6 +5.1439 +8.7378 +15.627 +33.325 +211.9 +60.397 +101.69 +1332.5 +3060 +4609.7 +1957.1 +212.12 +530.62 +459.73 +188.94 +107.74 +168.26 +140.91 +162.16 +627.7 +725.06 +1303.5 +418.4 +361.09 +553.24 +477.98 +257.37 +0.068583 +62.281 +74.97 +38.838 +24.013 +56.757 +13.842 +877.41 +633.51 +1581.6 +0.047724 +268.64 +458.73 +169.88 +80.418 +677.29 +695.39 +255.96 +37.205 +16.765 +49.366 +63.452 +57.471 +123.72 +170.14 +66.505 +65.926 +5430.1 +2961.3 +1700.5 +1172.6 +928.9 +1575.7 +0.21461 +9.7226 +24.895 +429.78 +234.85 +61.834 +249.54 +740.19 +3068.4 +5828.7 +1520 +1229 +491.2 +627.36 +75.631 +141.23 +285.98 +133.21 +178.42 +319.06 +308.66 +1294.3 +461.18 +447.44 +529.36 +654.58 +0.14097 +0.15739 +42.862 +43.728 +62.933 +14.411 +45.803 +8.4943 +435.44 +819.18 +0.072792 +0.038644 +0.012103 +0.19201 +118.95 +105.25 +945.04 +357.43 +241.32 +874.51 +10.599 +44.553 +95.873 +95.984 +92.944 +131.29 +47.153 +3520.4 +3212.7 +4248.5 +2582.6 +2092.5 +1678.6 +53.135 +0.069471 +7.6486 +53.938 +206.7 +110.02 +74.563 +424.97 +1881.9 +5918.7 +4586.8 +1687.3 +1662 +465.73 +622.63 +0.037337 +164.78 +293.03 +103.96 +327.39 +463.18 +471.76 +391.69 +211.72 +320.64 +344.15 +931.69 +0.094937 +0.0906 +35.584 +60.108 +41.609 +13.12 +15.302 +779.02 +363.35 +306.45 +0.089787 +0.030569 +0.033739 +0.64366 +114.74 +92.952 +387.66 +228.84 +112.24 +803.74 +332.45 +1272.9 +134.58 +71.012 +45.468 +119.03 +58.841 +267.25 +2309.6 +2630.8 +1756.5 +2424 +2443.7 +60.331 +0.11907 +0.14167 +63.106 +187.46 +104.66 +185.77 +186.8 +26.522 +9706.3 +3577.8 +1967.4 +924.07 +375.15 +582.36 +1425.1 +1132.3 +409.33 +100.11 +233.65 +281.67 +800.7 +381.51 +504.34 +423.49 +731.06 +410.49 +347.21 +0.074024 +0.019557 +42.297 +38.303 +9.8744 +18.558 +229.57 +248.25 +407.76 +0.26271 +0.06502 +0.12599 +0.15635 +0.094413 +253.74 +530.71 +347.99 +164.4 +1678.3 +645.46 +1617.5 +403.34 +56.769 +54.905 +204.75 +74.958 +136.17 +636.16 +1576.1 +3172.8 +5961.7 +1326.8 +868.74 +53.337 +52.886 +0.066584 +155.57 +116.53 +210.28 +112.91 +71.816 +5.6472 +3418.1 +1590.3 +541.64 +602.74 +393 +2265.5 +1488.6 +0.037064 +167.37 +276.11 +264.12 +279.67 +1058.9 +527.69 +521.93 +642.74 +713.74 +128.96 +1093.4 +37.365 +49.628 +28.63 +9.1692 +16.203 +177.19 +295.33 +95.657 +0.061756 +0.091459 +0.24849 +0.33318 +0.086877 +501.08 +1349.8 +823.09 +316.56 +1861.4 +1065.3 +718.59 +271.42 +346.54 +92.738 +142.07 +61.35 +312.77 +503.15 +356.05 +3065.2 +14441 +3915.6 +1743.8 +325.8 +88.939 +118.41 +0.15326 +140.31 +217.4 +174.92 +48.1 +8.0063 +1607.6 +1693.6 +440.18 +416.11 +167.17 +3106 +211.86 +211.42 +268.28 +264.78 +282.61 +318.27 +1025.1 +1196.8 +846.18 +375.89 +354.41 +233.28 +65.734 +26.272 +25.831 +39.663 +12.807 +533.47 +379.67 +368.2 +164.27 +0.078384 +0.11554 +0.082844 +0.31618 +553 +198.53 +723.76 +484.41 +442 +3142.8 +2471.6 +1773.3 +193.73 +241.07 +358.73 +211.15 +56.826 +255.63 +262.19 +741.48 +459.67 +12887 +6208.7 +3007 +386.33 +2103.1 +77.422 +160.82 +128.79 +217.44 +131.81 +101.89 +11.502 +1738.5 +822.3 +1040.2 +179.04 +103.33 +464.96 +66.585 +207.9 +277.95 +311.92 +449.82 +248.89 +812.64 +1627.6 +709.11 +453.64 +378.45 +491.83 +64.011 +29.601 +35.975 +29.799 +664.47 +297.62 +513.99 +722.17 +142.55 +0.20575 +0.058017 +0.15077 +207.84 +560.63 +454.59 +563.35 +1058.5 +351.9 +3496.2 +2501.5 +3437.6 +270.15 +457.24 +409.05 +249.73 +114.22 +213.91 +426.6 +297.57 +262.89 +938.64 +7730.1 +2040.3 +838.85 +1542.2 +168.08 +307.29 +143.34 +294.1 +212.66 +115.91 +9.7039 +12.762 +1601 +377.93 +597.62 +138.19 +171.62 +65.317 +231.28 +138.16 +302.66 +1388.8 +457.5 +614.03 +686.75 +638.82 +440.39 +120.63 +77.634 +76.019 +51.889 +76.537 +0.22543 +284.39 +352.74 +367.84 +547.59 +381.31 +0.13935 +0.25902 +203.51 +90.192 +273.14 +538.77 +424.09 +1983.5 +473.25 +2627.3 +1195.4 +5353.6 +1206.2 +532.9 +673.63 +165.7 +162.53 +141.46 +408.17 +317.96 +271.79 +753.58 +1009.3 +0.072567 +1032.2 +187.01 +311.51 +268.02 +126.12 +110.86 +189.38 +150.68 +33.989 +15.462 +231.63 +316.34 +380.13 +115.43 +130.05 +71.707 +562.86 +477.46 +527.93 +1558.3 +1960.3 +224.8 +525.93 +416.59 +191.89 +82.503 +140.25 +106.87 +57.258 +0.021598 +431.39 +455.88 +904.79 +550.3 +393.87 +423.39 +145.38 +51.405 +108.13 +51.997 +362.21 +364.75 +656.58 +2086.6 +528.73 +1289.6 +923.89 +2732.1 +331.25 +884.78 +341.21 +155.31 +149.71 +218.46 +119.18 +174.57 +452.53 +773.07 +679.24 +266.37 +142.94 +97.683 +380.37 +149.4 +134.4 +121.81 +500.84 +501.78 +67.229 +31.939 +462.75 +341.69 +879.5 +209.23 +55.529 +86.01 +82.324 +928.47 +291.68 +522.37 +1145 +306.36 +218.21 +705.79 +134.13 +151.92 +179.66 +97.813 +24.116 +0.010359 +0.010067 +1127 +1205.6 +656.76 +620.3 +267.97 +216.94 +88.884 +165.88 +98.846 +377.21 +183.35 +700.05 +3735.4 +572.4 +1132.6 +730.33 +446.4 +287 +632.54 +393.18 +434.06 +158.4 +191.33 +84.412 +83.693 +939.47 +443.7 +941.02 +199.8 +115.8 +223.6 +465.88 +246.73 +136.06 +261.98 +700.52 +1562.8 +146.32 +127.78 +592.48 +263.74 +190.22 +161.35 +46.306 +56.946 +82.659 +2114 +115.17 +463.11 +0.14831 +245.82 +191.73 +184.58 +371.8 +326.49 +258.87 +63.576 +0.019762 +431.93 +159.85 +475.11 +1040.9 +1296 +841.54 +402.99 +480.07 +51.768 +164.51 +35.035 +215.17 +0.18259 +0.059901 +0.022297 +0.057724 +1241.7 +511.46 +711.68 +609.18 +666.9 +465.13 +290.3 +197.53 +139.85 +73.956 +47.989 +380.39 +311.4 +436.29 +507.97 +186.51 +99.542 +245.37 +266.8 +279.22 +332.02 +665.03 +1611 +1773.7 +4378.1 +74.561 +1272.9 +70.506 +187.63 +112.83 +107.31 +81.716 +1565.5 +187 +0.12202 +0.062345 +136.1 +293.82 +95.402 +315.8 +902.47 +118.94 +150.4 +96.962 +273.84 +1142.5 +801.58 +2156.8 +928.56 +834.15 +251.38 +1995.9 +0.0414 +0.1812 +0.083538 +0.049005 +0.020769 +0.037798 +0.088131 +0.11301 +484 +287.66 +884.71 +751.57 +661.48 +659.77 +887.06 +49.447 +41.445 +43.865 +90.55 +189.94 +189.66 +340.72 +485.29 +172.36 +376.19 +761.83 +5097.5 +1003.5 +652.8 +812.82 +920.85 +1189.6 +4819.4 +6391 +0.16031 +578.67 +96.86 +209.33 +141.24 +79.787 +254.55 +173.46 +0.1296 +0.13914 +0.067583 +305.9 +145.44 +168.87 +1369.7 +2647.2 +307.19 +105.53 +45.156 +1113.6 +707.42 +1885.1 +444.49 +508.44 +338.09 +762.05 +0.052344 +0.21712 +0.19312 +0.067138 +0.079995 +0.20295 +0.45774 +0.22191 +0.078884 +269.33 +1023.1 +1164.5 +1257.6 +660.13 +967.61 +47.455 +73.362 +25.471 +136 +288.71 +177.45 +287.67 +678.17 +280.27 +676.46 +2562.5 +5777.9 +858.92 +1096.5 +1223.6 +1513.9 +1692.3 +5694.7 +2247.1 +3084.9 +2246.8 +155.06 +93.068 +248.55 +57.639 +353.78 +174.1 +244.1 +0.2585 +0.096308 +0.067533 +290.04 +243.93 +1592.3 +3479 +1057 +726.94 +1480.3 +716.51 +357.35 +980.22 +430.01 +382.69 +354.13 +439.31 +0.11339 +0.30329 +0.094161 +0.15305 +0.092782 +0.95161 +0.29201 +0.12462 +1.1793 +116.13 +949.25 +1969.5 +1249.3 +2114.1 +1140.5 +58.849 +118.01 +21.139 +142.71 +196.98 +137.62 +259.94 +1482.5 +238.6 +462.89 +2906.3 +6953.8 +649.48 +178.38 +863.76 +1543.3 +1559.9 +2029.5 +1731.5 +1787.4 +2129 +795.17 +0.32004 +28.991 +50.484 +612.57 +141.55 +122.37 +134.45 +0.041731 +70.702 +51.923 +216.28 +993.01 +2016 +2013.5 +438.78 +1260.8 +746.74 +444.52 +351.23 +325.06 +543.78 +0.16315 +0.28269 +1.9011 +0.20684 +0.11267 +0.13311 +0.29577 +0.21237 +0.14125 +0.20694 +1143.2 +287.82 +1023.5 +1540.8 +1572.5 +1975.2 +1300.3 +46.896 +223.61 +110.88 +119.06 +144.77 +230.61 +362.28 +1128.7 +377.61 +743.6 +850.51 +499.9 +79.682 +81.761 +473.11 +1312.9 +1521.3 +1697.9 +1057.8 +1481.2 +138.08 +234.67 +482.04 +41.854 +70.885 +852.37 +208.12 +102.56 +431.75 +800.76 +149.19 +1667.3 +366.58 +567.42 +1308.7 +2441.6 +427.12 +204.49 +373.9 +393.3 +677.59 +54.114 +105.66 +0.19516 +0.86463 +0.40842 +0.63739 +0.11629 +0.20011 +0.12786 +0.2272 +0.65623 +0.145 +293.95 +435.86 +1092.5 +2019.2 +2179.2 +2114.2 +958.5 +52.593 +257.85 +326.96 +131.97 +129.86 +236.59 +369.02 +633.38 +383 +617.52 +562.76 +264.44 +46.024 +78.95 +426.66 +341.95 +752.15 +2187.7 +1842.8 +1619.1 +0.17471 +0.028696 +0.069955 +0.10603 +66.076 +10.379 +3.3762 +180.07 +171.89 +530.07 +1285.9 +918.53 +609.83 +670.38 +1298.7 +1063.2 +302.36 +235.14 +518 +592.44 +845.55 +0.11983 +71.873 +36.694 +0.38875 +0.19726 +0.43545 +0.04583 +0.077717 +0.12011 +0.10777 +0.211 +0.0708 +402.34 +404.73 +1402 +1299.1 +1455.1 +1231.3 +842.34 +109.15 +852 +392.77 +195.78 +93.879 +420.81 +595.3 +957.1 +134.47 +523.36 +629.52 +369.6 +47.113 +165.11 +450.18 +918.71 +1559.8 +2983.5 +866.86 +0.2149 +0.23093 +0.025442 +0.05904 +0.060502 +0.42906 +5.5339 +2.0516 +25.895 +18.375 +1486 +1062.2 +870.07 +878.63 +523.94 +1583.7 +1303.7 +606.72 +315.82 +263.27 +720.26 +1001.4 +0.32825 +0.19151 +0.04952 +28.273 +25.594 +0.17304 +0.10358 +0.062688 +0.032039 +0.066776 +0.11724 +0.053414 +338.72 +356.68 +670.42 +651.9 +1206.8 +2563.6 +2207.4 +123.79 +1133.4 +227.94 +99.542 +251.43 +420.14 +675.36 +190.71 +142.36 +305.95 +529.74 +381.57 +34.02 +281.94 +408.38 +1053.2 +1533.1 +85.86 +54.615 +0.045374 +0.018717 +0.052816 +0.15296 +0.10399 +0.26042 +2.0728 +10.824 +26.506 +33.959 +26.444 +1596.8 +715.5 +647.18 +437.92 +1536.1 +1037.4 +151.9 +143.99 +0.23796 +0.26085 +440.9 +987.14 +1110.2 +0.04756 +42.925 +31.724 +0.063343 +0.11335 +0.11661 +0.33646 +0.081637 +0.044376 +0.033464 +399.57 +634.47 +378.25 +251.18 +2234 +3176.5 +5028.2 +119.39 +191.37 +432.28 +1214.4 +259.53 +402.38 +399.25 +135.9 +120.39 +288.26 +1529.4 +715.89 +64.168 +235.29 +296.25 +67.732 +89.798 +80.856 +47.942 +84.504 +0.016953 +217.84 +25.735 +116.31 +42.733 +4.3546 +8.2096 +3.1987 +29.043 +87.264 +2195.9 +1737.5 +271.35 +907.2 +90.34 +154.6 +1210 +499.89 +365.24 +0.088524 +0.035878 +738.84 +339.29 +1786.6 +73.325 +41.285 +0.062174 +0.31851 +0.31385 +0.069932 +0.029129 +0.010351 +1044.1 +132.81 +151.32 +199.84 +217.41 +1888.5 +1323.9 +11074 +87.675 +162.49 +616.44 +1663.6 +379.04 +439.35 +378.99 +218.68 +161.71 +383.25 +1563.3 +639.04 +0.10046 +85.418 +114.94 +211 +97.754 +48.24 +55.1 +395.76 +303.97 +87.969 +18.556 +33.902 +9.5661 +2.7022 +4.9639 +10.163 +10.762 +193.61 +240.11 +1197.4 +390.26 +1074.4 +88.767 +0.12781 +964.92 +465.55 +250.53 +188.62 +0.062791 +0.1782 +0.058732 +3739 +108.34 +50.934 +41.785 +0.34159 +0.13706 +0.15684 +0.061521 +895.89 +356.27 +1748.3 +138.95 +107.55 +402.15 +1097.2 +956.96 +2323.6 +108.27 +287.88 +738.59 +1166.4 +486.63 +1031.1 +549.68 +1884.8 +131.24 +1201.6 +539.86 +90.43 +271.83 +40.584 +109.68 +190.63 +40.99 +49.597 +45.415 +333.59 +154.69 +138.68 +44.657 +36.135 +19.532 +4.7297 +7.7976 +8.9658 +5.7267 +56.34 +158.58 +681.4 +501.84 +3357.1 +4292.1 +104.53 +0.1353 +0.051941 +207.97 +375.6 +166.84 +457.15 +0.13671 +0.058822 +149.74 +110.95 +105.9 +114.77 +25.11 +0.05079 +2001.1 +652.04 +560.69 +2134.2 +692.44 +887.08 +217.61 +591.85 +1140.4 +2569.6 +577.13 +498.42 +318.15 +841 +1848.2 +36.32 +574.8 +917.55 +1476.8 +786.21 +265.55 +116.76 +258.44 +59.16 +104.83 +144.92 +69.731 +24.484 +129.36 +159.51 +214.09 +14.247 +32.715 +38.476 +20.739 +8.9799 +7.2342 +16.101 +16.781 +488.44 +538.64 +398.34 +828.09 +106.67 +41.871 +126.78 +0.086474 +0.10149 +0.069468 +1189.7 +189.32 +639.72 +1187.5 +113.05 +132.44 +292.97 +146.56 +64.735 +38.816 +18.292 +21.443 +669.52 +600.39 +123.62 +157.3 +571.08 +1317.9 +523.64 +1525.3 +0.11599 +756.27 +282.38 +699.47 +625.81 +159.69 +53.169 +1012.5 +593.44 +700.98 +433.49 +486.72 +42.075 +151.78 +65.416 +92.607 +102.08 +80.555 +63.733 +130.89 +112.36 +40.615 +16.801 +18.013 +33.207 +17.977 +7.4554 +7.0424 +0.035235 +502.52 +440.23 +178.9 +140.41 +418.76 +178.72 +153.36 +144.63 +0.034636 +0.01696 +0.066269 +37.02 +7.4215 +3.465 +49.714 +384.99 +0.2156 +0.97349 +0.53516 +96.312 +75.404 +50.96 +51.966 +24.959 +465.32 +130.91 +71.074 +89.912 +208.03 +54.671 +25.457 +25.383 +1533.3 +644.72 +280.6 +148.63 +205.22 +1.6084 +0.17917 +470.91 +798.8 +30.033 +116.39 +21.94 +163.12 +188.65 +78.267 +82.16 +87.656 +130.2 +78.487 +64.52 +63.097 +23.338 +41.577 +22.427 +0.26698 +0.07227 +2772.6 +1398.9 +643.92 +225.64 +217.87 +371.62 +340.65 +12.813 +54.096 +103.33 +29.891 +54.058 +57.133 +119.67 +18.702 +273.22 +804.63 +355.27 +255.94 +502.37 +320.26 +310.2 +153.4 +114.34 +24.718 +15.925 +112.02 +217.94 +7.3534 +39.109 +44.272 +22.159 +38.782 +52.373 +30.385 +426.14 +424.47 +718.53 +1029.4 +0.19847 +0.20153 +215.77 +376.5 +44.385 +73.167 +18.186 +297.67 +212.72 +199.79 +166.16 +89.559 +96.9 +153.11 +65.36 +35.015 +32.336 +69.954 +89.352 +143.53 +2648.3 +2124.5 +2055.1 +778.89 +283.17 +221.32 +300.02 +38.698 +15.083 +46.053 +10.561 +71.144 +91.034 +82.09 +0.12253 +0.89744 +0.076039 +477.82 +501.41 +400.27 +441.93 +193.22 +339.72 +257.01 +72.82 +28.552 +43.439 +52.568 +19.558 +46.297 +24.858 +121.14 +17.47 +37.452 +0.072465 +48.038 +581.68 +1130.3 +626.42 +360.05 +0.062185 +197.74 +365.28 +180.19 +68.968 +67.71 +41.945 +277.72 +402.31 +154.34 +143.06 +338.26 +158.11 +62.766 +20.549 +41.364 +33.542 +106.77 +82.653 +200.85 +2148.6 +1275 +1298.1 +265.27 +323.46 +379.42 +0.32796 +47.903 +41.26 +58.991 +31.091 +173.39 +0.1605 +0.12609 +0.17936 +0.64501 +0.17449 +0.074845 +113.57 +260.54 +464.95 +494.73 +31.947 +234.32 +68.536 +63.576 +47.772 +25.674 +18.393 +142.49 +0.024056 +0.097862 +0.073398 +0.21122 +0.41314 +451.36 +1749.5 +589.68 +442.76 +721.83 +3023.2 +220.99 +703.55 +231.9 +106.1 +47.596 +72.048 +107.79 +357.36 +195.69 +185 +37.987 +42.876 +36.504 +134.01 +139.19 +24.233 +109.73 +126.86 +198.37 +759.91 +530.42 +310.9 +180.98 +0.1226 +36.767 +77.535 +64.672 +48.156 +52.085 +31.238 +0.10014 +0.15015 +0.10824 +0.1616 +0.1384 +0.12659 +0.098371 +69.073 +103.85 +276.22 +386.44 +63.309 +24.329 +56.721 +46.97 +26.884 +23.512 +998.77 +34.931 +87.25 +0.067415 +0.86133 +0.076759 +0.18656 +48.34 +27.538 +736.54 +381.83 +246.49 +3545.6 +1.2773 +923.19 +247.82 +293.97 +146.83 +129.83 +71.032 +143.47 +157.1 +70.291 +57.068 +18.112 +256.04 +95.5 +150.79 +19.047 +106.18 +142.36 +627.8 +854.45 +482.76 +0.041095 +482.13 +479.89 +34.668 +32.237 +11.149 +21.67 +36.577 +0.055264 +0.030211 +0.18916 +0.041197 +0.23012 +0.25767 +0.18535 +68.385 +34.255 +114.24 +558.09 +375.53 +67.427 +124.55 +66.604 +131.56 +26.305 +1926.7 +785.01 +0.44827 +0.04744 +59.846 +0.77496 +2.5935 +0.54714 +29.221 +17.378 +5.937 +209.38 +259.79 +868.79 +1739.2 +1014.6 +299.42 +205.64 +153.05 +85.944 +126.24 +188.37 +648.38 +172.7 +138.04 +66.191 +181.49 +95.369 +199.56 +22.052 +47.261 +74.439 +1052.5 +1013.8 +0.021778 +0.03919 +337.48 +1055.3 +50.16 +0.021448 +0.063402 +17.59 +12.243 +0.039517 +0.038394 +0.025718 +0.10192 +0.36288 +0.32193 +0.54223 +30.582 +16.386 +92.145 +304.81 +383.42 +138.95 +179.72 +16.896 +92.312 +860.9 +628.1 +657.3 +290.21 +0.07433 +0.073695 +0.48336 +0.87667 +0.71858 +15.273 +10.698 +8.2003 +12.525 +168.34 +1166.4 +844.42 +586.8 +232.44 +608.06 +115.58 +94.907 +161.09 +231.07 +520.7 +1039 +0.13615 +0.18525 +171.62 +1927.5 +104.85 +39.486 +30.53 +114.67 +594.84 +178.76 +0.071796 +0.11671 +755.1 +1745.4 +186.86 +0.024138 +19.824 +27.499 +18.195 +197.23 +0.30233 +0.083009 +0.5889 +0.79994 +0.21453 +0.28394 +0.090087 +29.891 +24.294 +145.38 +179.98 +147.61 +210.05 +92.321 +41.721 +619.25 +295.13 +556.6 +379.09 +596.95 +0.12375 +0.40087 +0.88514 +0.32101 +13.412 +7.8664 +2.9874 +11.833 +11.58 +18.667 +681.14 +311.61 +316.88 +342.53 +179.22 +157.69 +266.2 +252.09 +525.57 +348.8 +0.070855 +0.11907 +117.89 +1087.3 +1101.7 +49.618 +31.649 +45.615 +221.72 +138.91 +226.83 +1036.4 +875.82 +2119.6 +211.48 +0.018352 +0.028232 +13.519 +36.264 +169.34 +0.066552 +0.13617 +0.6378 +4542.5 +726.64 +30.05 +51.642 +25.493 +30.622 +157.78 +67.765 +139.04 +177.89 +37.449 +44.514 +0.14375 +487.75 +558 +265.24 +443.11 +1384.5 +0.80981 +0.38665 +0.33736 +4.7574 +26.617 +4.7194 +14.607 +14.744 +147.59 +90.592 +456.43 +408.08 +81.184 +67.094 +31.248 +27.379 +281.48 +324.56 +176.9 +0.13061 +71.589 +181.24 +254.15 +573.5 +466.88 +20.069 +55.479 +70.557 +139.58 +127.47 +1490.6 +788.72 +1028 +0.038751 +0.015453 +37.693 +20.275 +32.217 +167.26 +125.91 +4867.5 +8877.5 +4744 +817.33 +35.749 +59.325 +958.25 +195.81 +258.71 +63.075 +156.37 +150.81 +431.78 +1187.2 +0.028357 +375.99 +838.73 +222.5 +394.75 +1870.8 +0.30641 +0.14258 +0.42786 +20.021 +11.69 +5.4684 +19.84 +652.16 +492.08 +174.88 +328.01 +51.1 +97.463 +65.539 +55.23 +7.7214 +14.614 +37.193 +102.32 +2533.2 +585.09 +185.49 +216.1 +651.95 +520.27 +300.72 +58.958 +81.609 +97.312 +75.948 +1433.3 +907.35 +1241.7 +0.05995 +0.070423 +0.44508 +20.826 +59.671 +697.72 +274.65 +346.65 +169.15 +241.8 +290.14 +71.349 +0.47021 +793.28 +224.12 +273.63 +146.82 +148.06 +179.88 +232.27 +613.69 +9.4024 +0.096808 +760.82 +345.81 +430.79 +2224 +459.39 +0.19736 +0.1455 +62.836 +18.177 +204.45 +121.54 +632.85 +862.34 +70.088 +138.22 +129.8 +47.968 +29.455 +66.806 +13.889 +14.37 +43.484 +36.818 +854.44 +1062 +255.67 +201.24 +550.02 +5286.2 +296.44 +155.38 +99.316 +40.106 +169.44 +740.98 +1306.1 +1103.8 +0.25605 +0.35843 +2106 +484.96 +2220.6 +834.45 +330.34 +509.35 +2414.1 +2819.7 +635.36 +0.07977 +0.32448 +520.02 +222.09 +241.45 +226.28 +125.64 +340.08 +299.6 +435.55 +9.7728 +0.1244 +0.05853 +206.18 +827.09 +2866.4 +1257.7 +0.45667 +0.36313 +83.731 +167.17 +190.1 +97.632 +296.33 +335.35 +85.532 +310.68 +219.25 +155.37 +31.289 +61.146 +27.941 +13.055 +46.185 +183.23 +1213.5 +784.46 +318.82 +195.94 +110.56 +3865.2 +3891.2 +85.209 +224.04 +34.712 +115.14 +518.04 +876.01 +1716.3 +428.32 +315.64 +846.44 +372.49 +1481.4 +1189.4 +261.56 +580.89 +3189 +2509.4 +0.10297 +0.046378 +0.074906 +0.31122 +145.46 +334.43 +538.64 +393.19 +74.503 +114.16 +135.53 +5.8721 +11.169 +0.13823 +124.64 +418.85 +1429.5 +710.15 +335.69 +0.52072 +88.318 +59.52 +152.28 +128.36 +459 +248.28 +117.47 +450.69 +0.17389 +288.08 +27.099 +112.61 +40.598 +28.644 +49.515 +394.32 +3566.4 +1099.1 +335.89 +1098.3 +0.011366 +3284.4 +2602.6 +4333 +127.79 +51.8 +264.84 +499.72 +373.39 +557.13 +436.43 +493.29 +660.56 +479.86 +276.32 +203 +210.16 +391.62 +0.20188 +0.070393 +0.049973 +0.08111 +0.073274 +0.095156 +681.82 +942.6 +465.85 +217.13 +103.9 +65.016 +96.499 +13.8 +9.1091 +37.956 +79.985 +234.87 +999.19 +610.2 +454.25 +0.091811 +85.753 +61.127 +121.42 +96.061 +446.39 +237.38 +101.94 +1025.5 +489.33 +242.65 +325.84 +156.06 +40.599 +67.447 +148.68 +1049.7 +2957.5 +1510.6 +630.23 +1094.6 +113.4 +1730.1 +1956.6 +2528 +1088.7 +129.32 +634.36 +369.34 +410.17 +476 +469.77 +14.374 +17.996 +126.14 +289.74 +605.85 +210.27 +391 +0.042449 +0.16027 +0.016946 +0.015409 +0.068875 +43.138 +290.34 +818.35 +641.98 +482.93 +136.26 +77.203 +2.7069 +4.0845 +5.8779 +15.019 +44.188 +414.64 +1083.9 +921.65 +251.23 +0.13003 +90.357 +42.585 +86.969 +64.45 +876.14 +234.04 +56.997 +607.64 +490.28 +44.936 +354.53 +80.268 +27.515 +89.532 +155.06 +906.25 +904.35 +1330.4 +535.8 +1563.8 +3740.5 +1248.5 +2045.5 +1590.2 +2510.2 +52.266 +111.12 +459.63 +683.51 +685.6 +15.426 +12.24 +19.932 +150.57 +189.68 +286.29 +189.83 +0.08544 +0.18577 +0.023424 +0.08264 +0.052771 +55.624 +134.85 +504.88 +1489.3 +827.4 +517.05 +122.22 +8.8171 +1.9658 +2.0627 +7.633 +16.331 +23.068 +960.95 +2077 +774.08 +132.74 +0.36926 +82.21 +110.38 +54.136 +184.39 +196.02 +205.28 +125.46 +452.06 +313.96 +58.049 +14.138 +53.612 +25.246 +81.582 +266.45 +1284.3 +1107.6 +1339.7 +1063.3 +1211 +24.905 +1164.2 +1491.3 +1946.3 +0.085308 +0.019249 +48.907 +759.51 +1457.7 +64.646 +14.602 +18.561 +35.899 +60.252 +611.88 +506.13 +753.37 +0.097946 +0.025892 +0.035392 +0.045721 +0.15179 +172.56 +350.25 +776.41 +765.26 +720.35 +453.6 +16.471 +13.518 +34.595 +0.026014 +10.297 +7.36 +19.813 +39.628 +2455 +1968.5 +172.31 +0.52791 +85.927 +79.914 +106.9 +181.64 +348.37 +271.77 +180.58 +339.07 +240.03 +81.512 +15.008 +58.916 +45.367 +70.907 +126.54 +1357.8 +734.45 +844.5 +1266 +1131.1 +22.526 +0.17569 +539.77 +577.78 +267.14 +310.94 +375.76 +181.61 +875 +74.623 +284.96 +293.64 +2150.2 +803.33 +530.64 +825.42 +470.08 +0.017569 +0.055829 +0.045731 +0.063918 +220.91 +345.71 +335.74 +768 +1187.2 +0.1844 +10.574 +24.056 +11.499 +20.784 +18.517 +0.049389 +7.2861 +9.3063 +31.541 +46.434 +4960 +111.13 +0.28127 +132.79 +88.241 +178.62 +197.21 +640.15 +541.34 +522.28 +294.69 +405.12 +273.26 +38.131 +420.76 +45.479 +91.787 +0.85474 +1272.7 +679.76 +582.39 +567.89 +955.26 +32.407 +889.39 +1324.6 +355.64 +295.44 +221.51 +557.73 +42.52 +72.62 +102.29 +150.01 +133.33 +143.63 +212.3 +370.14 +309.8 +558.49 +0.023853 +0.12282 +0.24652 +172.19 +208.16 +204.22 +383.75 +327.65 +2180.6 +0.32733 +10.5 +8.8149 +20.456 +25.376 +13.497 +150.37 +45.274 +11.425 +18.958 +46.069 +19.463 +0.30165 +0.16494 +129.46 +71.32 +1351.9 +214.33 +1241.8 +455.46 +1405.8 +186.4 +301.11 +422.31 +77.404 +161.28 +235.82 +0.70436 +0.50665 +10294 +578.6 +205.7 +378.31 +247.09 +1722.7 +1064.5 +860.58 +59.366 +125.87 +251.88 +142.26 +50.057 +4358.2 +123.92 +233.85 +317.28 +230.24 +323.35 +237.27 +685.12 +401.23 +466.28 +0.11989 +394.21 +218.89 +144.43 +225.62 +236.91 +0.030465 +0.11116 +0.095551 +0.55263 +9.072 +18.694 +17.052 +13.882 +71.084 +31.57 +128.3 +20.847 +42.064 +17.91 +7.5684 +0.40808 +130.04 +147.14 +590.84 +1294.9 +967.55 +851.26 +475.61 +141.3 +411.69 +802.86 +162.96 +134.36 +230.06 +117.62 +0.36558 +6324.8 +169.88 +296.16 +473.38 +336.53 +1806.5 +2030.7 +173.86 +62.638 +100.26 +440.71 +114.14 +0.40009 +0.30926 +117.54 +110.41 +152.75 +119.06 +193.18 +212.46 +369.12 +0.1836 +508.84 +728.21 +938.31 +292.01 +231.21 +293.95 +304.89 +0.033314 +0.10135 +0.15282 +0.6723 +7.3363 +237.48 +66.958 +12.629 +61.721 +42.823 +253.66 +73.954 +24.763 +18.83 +8.2548 +30.659 +75.263 +970.26 +541.67 +799.48 +1033.2 +581.86 +502.57 +940.34 +420.19 +800.28 +209.65 +101.09 +41.289 +142.82 +62.857 +59.003 +176.32 +115.49 +300.26 +303.52 +3794.6 +87.911 +60.359 +65.53 +112.22 +173.64 +106.76 +34.379 +126.42 +137.34 +91.491 +101.56 +62.362 +173.72 +145.94 +232.28 +9.5405 +0.1921 +0.16813 +664.93 +610.52 +130.54 +192.13 +313.85 +0.15819 +0.1108 +0.052321 +252.69 +93.038 +123.49 +34.536 +19.187 +13.554 +40.676 +133.78 +0.012091 +40.135 +28.928 +20.715 +35.891 +1993.6 +571.15 +581.84 +466.08 +877.04 +470.9 +65.902 +1482.9 +2285.2 +635.27 +305.04 +130.16 +38.112 +97.83 +127.99 +46.226 +96.815 +74.322 +52.556 +149.49 +25.225 +72.068 +72.47 +143.92 +157.84 +0.16203 +37.039 +39.236 +75.323 +232.44 +1630.5 +2434 +121.68 +456.96 +227.48 +130.49 +29.916 +0.58132 +0.067805 +57.089 +239.3 +1148 +136.89 +112.34 +79.663 +0.13417 +0.19175 +0.12631 +260.86 +194.99 +63.405 +9.054 +15.465 +40.581 +0.023232 +0.021142 +0.0293 +21.144 +22.945 +87.37 +1917.5 +915.26 +612.26 +668.67 +735.86 +141.87 +736.14 +560.49 +3120 +354.12 +556.35 +73.302 +59.177 +126.23 +101.26 +32.884 +73.783 +39.784 +42.599 +46.013 +55.69 +63.69 +127.89 +361.11 +44.252 +48.617 +76.659 +47.136 +36.383 +0.086091 +0.13785 +1529.2 +83.681 +918.35 +329.61 +238.79 +34.485 +384.83 +0.40877 +0.11751 +184.83 +853.47 +937.13 +625.27 +30.09 +98.193 +66.893 +0.16512 +712.46 +250.24 +239.78 +16.532 +0.022769 +97.087 +0.082615 +0.030556 +0.039495 +0.076921 +0.03297 +0.13081 +1880.1 +790.72 +571.21 +130.62 +97.113 +83.986 +188.47 +3240.8 +2285.4 +424.58 +533.96 +822.4 +790.61 +190.68 +530.97 +1025.2 +517.29 +57.51 +46.469 +32.37 +68.906 +35.758 +46.614 +37.095 +22.332 +41.674 +128.95 +33.061 +59.754 +0.061617 +0.16163 +0.085615 +61.675 +2246.1 +529.12 +196.44 +70.135 +506.35 +1803.9 +321.68 +842.86 +568.03 +722.48 +340.02 +0.11562 +0.42642 +0.78126 +52.659 +60.41 +115.34 +138.52 +18.54 +0.013211 +0.0147 +0.067439 +0.055727 +0.094388 +0.17427 +0.029811 +0.090882 +2428 +830.66 +617.91 +78.124 +109.96 +48.02 +205.06 +157.11 +116.5 +147.26 +622.43 +677.23 +447.27 +366.81 +599.54 +999.03 +1350.8 +430.52 +54.272 +48.573 +115.9 +84.68 +86.391 +9.7096 +6.48 +30.083 +60.887 +0.055544 +0.11493 +0.29547 +0.10904 +0.046772 +164.55 +848.45 +770.61 +155.78 +219.23 +620.98 +668.22 +1321.1 +659.43 +823.87 +295.02 +227.58 +0.33073 +0.21478 +0.21812 +0.88187 +87.352 +94.317 +79.113 +55.839 +25.99 +0.11826 +0.0463 +0.20368 +0.15934 +0.20266 +0.078118 +0.17133 +1269.2 +694.96 +898.92 +130.92 +98.952 +19.79 +274.99 +67.228 +61.322 +407.21 +242.26 +738.27 +357.11 +250.49 +633.53 +1035.8 +1193.8 +66.531 +119.53 +8.9408 +65.479 +131.95 +109.4 +20.582 +17.322 +19.266 +0.25694 +0.30751 +0.21913 +0.1033 +0.032373 +0.1699 +370.56 +1102.2 +899.91 +310.19 +116.45 +471.68 +2196 +0.2517 +539.89 +367.52 +279.07 +248.3 +120.78 +1.4623 +0.56745 +0.12788 +0.16452 +0.2811 +69.861 +120.9 +24.2 +0.057783 +0.053848 +0.34549 +0.30368 +0.11393 +0.13671 +0.049957 +4577.6 +1355.6 +1169.1 +1865.3 +1300.1 +22.046 +276.4 +38.201 +112.11 +141.8 +121.27 +812.69 +339.75 +340.72 +1749.8 +1232.2 +790.75 +119.01 +35.604 +19.792 +55.792 +91.544 +83.599 +39.487 +14.554 +28.944 +0.095537 +0.34267 +0.12202 +0.072427 +0.092746 +0.10909 +0.055135 +1129.7 +1053 +659.98 +118.1 +280.91 +1990.4 +0.10124 +0.095934 +186.43 +173.01 +231.54 +162.3 +160.33 +170 +0.19699 +0.084227 +0.12183 +50.555 +115.97 +239.76 +202.39 +565.23 +0.050472 +0.13295 +0.15889 +0.00915 +0.064198 +0.16449 +2256.4 +936.02 +795.29 +1198 +346.32 +722.52 +22.909 +74.286 +417.16 +113.5 +453.31 +206.37 +727.65 +1359.7 +2645 +266.94 +111.19 +46.713 +35.39 +33.117 +92.538 +93.318 +40.804 +22.519 +73.753 +202.11 +0.18169 +0.10232 +0.088391 +0.24022 +392.76 +1537.5 +3303.2 +1546.3 +473.38 +327.6 +569.55 +506.92 +181.99 +504.2 +0.20371 +108.06 +205.52 +163.71 +209.54 +235.48 +308.7 +615.5 +0.025609 +0.10415 +15.16 +18.585 +206.75 +614.82 +1118.3 +0.061337 +0.079986 +0.060736 +0.079614 +0.2289 +144.87 +46.092 +68.88 +1366.4 +380.28 +200.68 +315.58 +111.99 +209.48 +163.25 +277.06 +295.44 +219.27 +2084.6 +3052.7 +132.12 +176.53 +92.845 +66.584 +54.093 +46.612 +78.561 +34.317 +146.96 +86.729 +205.64 +55.682 +0.079042 +0.14217 +0.1425 +739.8 +1316.8 +2588 +4526.7 +2313.3 +380.75 +135.57 +379.73 +367.82 +560.19 +970.25 +71.486 +79.599 +97.699 +82.987 +105.01 +882.96 +489.95 +599.38 +698.06 +453.94 +22.206 +75.62 +335.74 +587.02 +282.35 +0.040447 +0.088218 +0.16329 +77.803 +77.391 +119.72 +12.219 +5.9061 +156.03 +278.35 +376.06 +437.36 +190.64 +122.54 +565.25 +682.91 +359.68 +2707.6 +0.072793 +95.906 +114.09 +75.068 +34.858 +60.153 +26.578 +47.649 +282.6 +130.3 +84.802 +140.3 +67.09 +30.589 +0.059206 +742.48 +875.83 +639.03 +1406.1 +4081.3 +929.86 +1336.9 +323.74 +254.24 +241.76 +661.21 +1313.4 +43.589 +42.922 +66.418 +49.554 +134.98 +60.055 +1197.3 +761.6 +986.42 +399.33 +482.13 +162.2 +407.89 +1052.3 +304.01 +0.063463 +0.047209 +0.024671 +63.195 +66.695 +51.83 +53.94 +113.37 +140.95 +114.71 +229.29 +1029.4 +1612.3 +5387.4 +5003.9 +243.19 +9380.7 +923.37 +50.165 +186.82 +277.69 +113.39 +67.843 +59.106 +15.583 +25.626 +20.198 +222.9 +23.408 +83.357 +48.15 +48.912 +0.16764 +656.39 +509.97 +250.51 +527.53 +822.98 +763.49 +1325.4 +441.61 +384.69 +252.12 +0.62489 +0.050631 +41.746 +43.172 +74.317 +60.967 +55.314 +5334.2 +3800 +2996.8 +1119.5 +260.93 +231.5 +307.88 +213.3 +443.96 +392.29 +0.22197 +0.08749 +0.030671 +727.22 +124.38 +84.005 +81.797 +292.63 +247.03 +115.11 +291.74 +881.73 +2682.8 +4328 +5540.3 +5323.4 +86.462 +281.39 +81.598 +179.21 +151.75 +65.767 +112.55 +32.61 +10.206 +19.956 +117.73 +109.03 +57.502 +53.756 +37.745 +80.822 +385.81 +659.12 +674.45 +468.03 +562.78 +1135.6 +460.75 +1074.8 +499.6 +283.92 +395.5 +1236.5 +1638.2 +53.248 +112.71 +69.911 +128.9 +60.747 +4309.6 +2865.6 +2328.2 +624.18 +185.71 +353.75 +239.71 +253.09 +286.23 +0.1082 +0.13238 +0.064563 +0.03965 +334.88 +505.95 +86.81 +178.3 +663.96 +1075.5 +818.29 +577.13 +1774.9 +632.49 +164.9 +5470.9 +8943.5 +3742.9 +1345 +115.24 +144.01 +112.14 +107.65 +89.546 +41.104 +7.1019 +20.637 +43.597 +89.798 +75.311 +74.725 +116.86 +259.26 +455.68 +498.77 +502.82 +704.79 +523.69 +0.41684 +1301.5 +941.47 +1015.1 +251.64 +1433 +1582 +1398.3 +40.127 +198.85 +76.973 +120.06 +7388.2 +3835.5 +251.31 +244.94 +615.07 +301.95 +535.92 +374.12 +0.20206 +0.050042 +0.056924 +0.26609 +0.087839 +0.022109 +368.45 +438.24 +111.09 +132.05 +921.37 +808.9 +1019.5 +531.18 +2149.3 +435.63 +144.87 +230.64 +10643 +5898.3 +2026.1 +40.111 +188.47 +138.91 +168.82 +203.81 +42.116 +5.2948 +22.695 +35.925 +121.14 +612.33 +188.1 +57.532 +293 +570.36 +540.93 +408.08 +579.63 +0.15926 +0.81058 +0.04284 +803.55 +555.01 +437.07 +896.91 +1378.6 +159.61 +68.162 +254.39 +88.432 +14250 +2836.4 +31.255 +285.21 +323.57 +214.99 +90.656 +0.0804 +0.14419 +0.14268 +0.13 +0.053223 +0.15144 +0.29863 +0.035042 +492.88 +210.98 +94.369 +305.37 +662.38 +721.62 +1181.4 +489.78 +438.51 +1218.3 +97.78 +75.163 +4984.5 +4091.3 +60.795 +31.678 +124.76 +198.52 +176.61 +206.67 +37.318 +3.6301 +9.1312 +18.701 +134.01 +231.5 +97.791 +70.328 +279.16 +551.86 +816.88 +349.68 +563.94 +0.85929 +0.42366 +0.18717 +1002.1 +315.58 +666.87 +1031.4 +124.97 +86.975 +97.122 +217.14 +89.2 +872.74 +126.94 +53.245 +546.53 +572.12 +229.6 +0.059899 +0.017263 +0.16697 +0.16621 +0.3571 +0.18074 +0.022769 +0.047176 +0.23812 +434.36 +151.43 +38.136 +218.13 +882.65 +782.61 +1342.9 +1696 +1006.5 +357.73 +634.14 +49.816 +5397.2 +5469.8 +46.838 +33.119 +66.15 +185.11 +105.78 +225.73 +35.267 +14.78 +20.735 +27.536 +24.715 +121.73 +113.63 +55.759 +323.64 +206.89 +763.23 +0.42954 +0.12588 +0.38625 +0.29449 +0.043779 +0.27847 +543.34 +460.2 +1147.8 +238.92 +61.311 +181.05 +208.56 +508.39 +339.02 +175.28 +125 +164.62 +0.043501 +0.02866 +0.062457 +0.040213 +0.11443 +0.21913 +0.11669 +0.04374 +0.016654 +0.17227 +0.062289 +247.2 +218.31 +67.361 +200.25 +612.29 +242.55 +647.37 +2424.1 +1143.5 +952.74 +137.37 +53.519 +7754.5 +79.312 +94.58 +32.569 +77.014 +105.6 +98.382 +187.66 +23.153 +16.673 +23.345 +33.799 +50.45 +64.834 +157.59 +42.568 +261.19 +185.93 +614.25 +0.33103 +0.28102 +0.13799 +0.15294 +0.073055 +0.8494 +127.22 +462.39 +582.03 +179.22 +129.21 +983.13 +763.44 +137.08 +345.52 +88.9 +165.44 +27.223 +0.1583 +0.096839 +0.071621 +0.043791 +0.050473 +0.061135 +0.022685 +0.083898 +0.038899 +0.7427 +0.6071 +267.54 +198.31 +69.754 +84.708 +390.57 +708.21 +2934.1 +1721.4 +1116.8 +1230.7 +174.38 +9386.7 +108.48 +139.66 +75.38 +26.515 +120.66 +108.66 +89.76 +344.93 +74.355 +68.365 +34.298 +28.465 +48.124 +70.851 +96.992 +61.976 +371.84 +1575.1 +1094.2 +342.1 +0.077362 +0.076971 +0.05553 +0.12666 +295.68 +252.99 +382.44 +483.03 +458.97 +85.039 +498.06 +810.13 +103.07 +208.19 +161.99 +125.81 +0.1919 +0.12191 +0.037021 +0.29284 +0.052602 +0.32042 +0.046684 +0.1262 +0.44467 +0.64395 +0.06337 +0.2208 +223.39 +273.76 +67.621 +70.992 +506.43 +851.67 +2396.2 +1877.6 +62.199 +28.433 +732.63 +765.14 +220.15 +235.48 +61.016 +26.896 +87.236 +70.419 +203.86 +357.74 +58.619 +70.907 +334.52 +60.353 +98.742 +99.331 +142.46 +37.093 +187.75 +1227.5 +1563.1 +300.69 +0.064358 +0.18656 +81.927 +46.866 +250.13 +291.85 +794.61 +735.84 +667.5 +206.08 +413.8 +139.57 +101.27 +34.505 +106.77 +0.10019 +0.11337 +0.081098 +0.13903 +0.17152 +0.057469 +0.27896 +0.089418 +0.73589 +0.32431 +0.64672 +0.34203 +0.065661 +160.32 +80.67 +123.31 +179.51 +350.25 +5073 +3533.3 +115.99 +157.95 +8106.2 +1879.3 +648.6 +84.411 +303.74 +100.71 +38.849 +86.472 +161.51 +263.09 +195.46 +89.781 +39.924 +225.73 +42.995 +78.674 +53.808 +94.261 +88.364 +373.94 +996.86 +1341.8 +464.36 +0.039879 +65.058 +91.046 +81.726 +381.79 +1495.5 +683.13 +1123.8 +517.43 +163.17 +24.442 +40.156 +38.388 +25.15 +94.066 +0.024743 +0.068258 +0.19848 +0.93696 +1.4281 +0.11725 +0.15148 +0.1642 +0.23464 +0.22145 +0.19224 +2.505 +0.70668 +201.05 +90.126 +126.88 +1190 +777.07 +4899.7 +678.77 +1130.2 +6.7953 +10596 +3770.2 +779.21 +176.74 +157.91 +168.41 +66.738 +76.78 +96.715 +182.56 +18.197 +54.624 +44.979 +83.368 +60.242 +73.634 +65.679 +70.81 +537.25 +451.41 +719.55 +1099.7 +340.66 +322.84 +40.488 +616.53 +3816.4 +1162.9 +1224.5 +416.71 +1044.3 +9063.2 +70.761 +17.786 +76.351 +27.221 +10.547 +16.9 +0.021039 +0.045338 +0.095938 +0.13353 +0.31105 +0.055649 +0.083421 +0.044455 +0.016204 +0.14049 +0.34422 +0.09559 +0.34635 +140.15 +1944.3 +836.85 +359.34 +380.13 +902.41 +896.1 +916.53 +260.12 +5520.8 +1990 +487.75 +384.89 +111.42 +189.71 +50.02 +137.73 +165.61 +67.841 +17.14 +69.179 +42.488 +52.427 +84.819 +103.17 +44.679 +83.167 +342.59 +1181.8 +378.38 +1105.3 +410.63 +8129.5 +2901.9 +627.33 +1594.8 +725.26 +1002.6 +0.09602 +0.063524 +6443.4 +103.58 +26.237 +86.196 +51.087 +25.939 +31.543 +0.014291 +0.004506 +0.030525 +0.15593 +0.18315 +0.043413 +0.24672 +0.046868 +0.14889 +0.18599 +1.9303 +0.37693 +0.41698 +630.52 +944.82 +97.564 +296.6 +185.71 +986.83 +1218 +1653.2 +469.28 +3312.5 +1509.8 +443.92 +330.44 +123.85 +136.11 +39.228 +159.79 +0.73861 +30.21 +40.968 +27.758 +59.848 +46.37 +1098.8 +43.889 +98.104 +40.548 +235.48 +669.96 +348.12 +370.51 +243.04 +4807.6 +3606.9 +576.44 +1256.6 +0.30355 +0.17953 +0.29701 +0.053853 +5896.5 +50.044 +46.258 +47.816 +42.806 +69.952 +106.56 +0.34318 +0.025863 +0.1704 +0.13901 +0.095444 +0.092367 +0.12837 +0.018696 +0.016011 +0.044065 +0.1034 +0.068349 +0.1808 +619.98 +312.02 +129.54 +279.42 +216.25 +123.29 +983.97 +3944.9 +543.57 +3465.9 +1794.2 +315.24 +364.92 +128.76 +316.27 +40.732 +118.16 +1.2723 +46.693 +17.538 +73.975 +108.89 +99.22 +125.81 +113.48 +227.24 +75.975 +202.5 +902.64 +434.51 +241.82 +7366.6 +5050.8 +5326 +98.017 +69.843 +0.16565 +0.25871 +0.077979 +0.077727 +202.77 +44.166 +74.829 +52.991 +37.051 +79.419 +245.29 +188.46 +0.022691 +0.013789 +0.14137 +0.053556 +0.10356 +0.11882 +0.10259 +0.019621 +0.043758 +0.20601 +0.11421 +0.42741 +1109.6 +2030.4 +2451.1 +313.58 +596.71 +125.66 +135.84 +442.03 +778.45 +810.21 +738.1 +315.35 +382.64 +106.18 +173.69 +84.679 +92.843 +17.735 +65.789 +39.076 +56.094 +163.55 +164.85 +495.57 +125.21 +269.44 +118.81 +242.01 +929.05 +716.76 +4381 +4876.5 +4573 +148.31 +96.322 +59.475 +0.042397 +0.076226 +0.13975 +456.51 +118.43 +34.431 +67.079 +45.391 +34.866 +59.594 +104.74 +147.49 +0.10363 +0.056511 +0.14809 +0.098921 +0.031666 +0.025205 +0.11921 +0.045407 +0.094984 +0.23079 +0.096631 +0.10193 +1.6416 +4695.7 +294.95 +3856.5 +302.47 +31.979 +65.641 +462.15 +704.75 +917.91 +575.57 +175.31 +231.62 +176.22 +98.136 +80.741 +111.14 +19.508 +34.909 +14.136 +30.208 +186.59 +73.34 +291.55 +276.49 +240.13 +418.12 +234.08 +607.79 +2757.4 +4920 +2799.4 +4729.3 +2626.9 +128.68 +46.913 +0.0726 +0.072401 +841.44 +646.64 +224.38 +45.655 +60.483 +67.441 +355.93 +571.9 +179.15 +58.79 +197.9 +0.13627 +0.30573 +0.11765 +0.067013 +0.018219 +0.016733 +0.057497 +0.064122 +0.13514 +0.090312 +0.066371 +4.7209 +2.5143 +943.4 +322.96 +0.23517 +30.915 +100.11 +376.11 +337.24 +723 +1056.2 +761.33 +176.87 +55.933 +104.28 +81.898 +96.379 +71.783 +21.72 +10.677 +22.403 +153.35 +63.851 +97.804 +165.95 +296.34 +496.23 +184.7 +412.73 +43.664 +5602.1 +4002.9 +1860.3 +2679.2 +59.8 +50.525 +38.697 +775.63 +572.89 +1475.9 +336.99 +115.05 +649.9 +2193 +245.61 +744.1 +191.27 +84.952 +170.41 +0.026531 +0.1137 +0.027563 +0.028579 +0.017583 +0.017441 +0.005683 +0.024632 +0.040253 +0.13334 +0.18874 +4.8316 +5.5234 +535.21 +98.258 +998.54 +653.23 +20.796 +9.0748 +360.11 +1302.8 +1828.5 +1244 +933.62 +55.069 +69.321 +40.333 +36.342 +121.36 +10.116 +15.08 +36.442 +168.15 +122.2 +124.15 +278.44 +425.85 +468.23 +154.97 +126.34 +23.184 +50.346 +3712.7 +1466 +1793.8 +1386.8 +72.252 +51.122 +178.73 +551.67 +1585.6 +331.67 +348.35 +353.49 +1277.2 +635.25 +392.83 +91.123 +96.079 +227.47 +0.006421 +0.049285 +0.044429 +0.008224 +0.047792 +0.068893 +0.017327 +0.039469 +0.08043 +0.13022 +0.082486 +5.1338 +4.1562 +16.882 +141.76 +734.8 +2930.1 +323.75 +0.52506 +21.982 +1693.4 +1727.6 +1895.2 +957.11 +1074.9 +70.258 +52.68 +45.589 +210.09 +42.13 +10.354 +19.661 +79.071 +222.31 +67.117 +218.7 +193.49 +238.43 +296.85 +85.012 +40.904 +59.337 +3410.2 +1700.5 +1296.7 +2115.4 +2930.4 +20.937 +123.49 +62.511 +141.19 +327.3 +221.18 +240.25 +612.72 +330.89 +233.97 +80.032 +61.025 +116.47 +281.4 +0.35713 +0.029346 +0.027064 +0.035857 +0.045525 +0.006328 +0.048262 +0.072376 +0.089183 +0.25604 +3.9534 +6 +84.076 +112.48 +471.24 +1950 +230.46 +226.41 +233.52 +152.13 +1310.9 +1663.7 +779.52 +758.12 +405.68 +66.272 +65.105 +85.09 +58.834 +60.204 +18.779 +234.33 +104.95 +30.056 +12.884 +330.23 +366.01 +526.89 +130.22 +41.978 +39.877 +83.094 +672.33 +1758.8 +1338.8 +2849.5 +73.871 +95.442 +131.27 +78.909 +294.33 +273.98 +396.63 +483.5 +493.7 +244.6 +137.36 +84.581 +165.83 +181.96 +0.24078 +0.047571 +0.042202 +0.11999 +0.03037 +0.009228 +0.021816 +0.030977 +0.17975 +0.24829 +7.4315 +7.293 +52.933 +6.5971 +293.88 +4863.8 +928.3 +112.59 +183.04 +21.641 +15.022 +717.13 +1614.8 +629.28 +542.28 +142.76 +73.015 +66.367 +18.333 +61.114 +41.806 +59.816 +43.447 +37.07 +16.375 +455.18 +601.62 +1983.8 +127.05 +63.564 +9.1131 +81.932 +65.859 +145.19 +665.97 +3082.9 +4975.3 +277.61 +181.54 +86.337 +81.146 +293.29 +327.72 +1073.8 +512.55 +347.1 +134.98 +157.76 +265.3 +0.054571 +0.18742 +0.082125 +0.033194 +0.081653 +0.049311 +0.058793 +0.020303 +0.067323 +0.13689 +0.20344 +13.834 +9.772 +48.885 +12.516 +16.256 +4965.6 +1659.5 +141.05 +193.06 +35.968 +34.877 +52.472 +1344.1 +493.89 +612.7 +188.02 +52.916 +39.841 +20.352 +33.753 +15.054 +41.654 +106.28 +51.689 +14.346 +536.01 +672.32 +1050.8 +98.978 +107.55 +15.315 +67.565 +25.825 +90.562 +551.62 +3907.9 +2211.4 +297.49 +141.52 +74.294 +84.463 +497.94 +321.86 +798.51 +997.35 +245.92 +207.91 +289.35 +0.067189 +0.12025 +0.11858 +0.3864 +0.10523 +0.3428 +0.18746 +0.034576 +0.089765 +0.059297 +0.10473 +0.15225 +13.86 +12.321 +31.326 +8.9195 +323.04 +134.71 +145.97 +451.24 +59.115 +55.685 +85.474 +88.555 +15.423 +555.67 +479.14 +128.05 +150.63 +41.16 +23.577 +29.607 +19.572 +39.653 +43.109 +160.17 +80.801 +224.67 +1174.8 +861.35 +152.29 +315.12 +194.56 +111.59 +30.172 +65.475 +134.45 +87.755 +1186.3 +223.71 +353.59 +128.69 +151.5 +268.89 +968.96 +1414 +744.6 +320.58 +282.53 +249.62 +0.24849 +0.29093 +0.25982 +0.99116 +0.3283 +0.11002 +0.048244 +0.043303 +0.072392 +0.17545 +0.15748 +0.36863 +23.905 +11.748 +21.218 +14.339 +882.83 +0.18589 +229.16 +67.704 +51.019 +60.503 +77.169 +186.56 +51.586 +226.58 +404.33 +171.54 +152.9 +60.561 +24.917 +57.242 +9.1754 +32.435 +40.515 +80.929 +348.09 +111.32 +215.36 +47.265 +134.04 +321.31 +58.288 +80.063 +73.861 +51.005 +122.88 +61.66 +84.99 +103.96 +163.11 +97.962 +366.93 +65.736 +1681.3 +891.47 +1001.1 +361.26 +0.066279 +1.296 +0.32493 +0.25601 +0.095479 +0.46714 +0.24702 +0.89324 +0.098013 +0.035136 +0.018783 +0.17505 +0.072354 +0.055295 +33.351 +16.96 +8.6701 +8.6353 +1357.9 +17071 +40.055 +73.379 +11.504 +60.006 +75.506 +97.137 +81.796 +176.72 +449.69 +284.16 +284.44 +64.221 +22.822 +42.988 +6.3771 +31.072 +155.39 +84.027 +343.38 +102.21 +129.57 +151.28 +89.326 +0.3188 +71.084 +105.42 +165.84 +125.81 +80.866 +98.395 +400.75 +125.72 +136.44 +81.719 +165.66 +63.942 +32.455 +527.23 +0.2479 +0.61274 +0.17505 +0.083339 +0.040549 +0.11917 +0.023824 +0.012139 +0.084957 +0.17797 +0.031481 +0.033224 +0.097474 +0.072072 +0.25574 +0.021377 +81.456 +41.589 +17.169 +15.404 +18.925 +137.16 +71.361 +64.516 +24.209 +43.195 +48.634 +196.69 +93.569 +225.12 +269.47 +95.372 +97.168 +79.84 +43.41 +64.213 +22.325 +161.14 +161.91 +112.26 +381.76 +61.769 +42.907 +56.459 +53.078 +28.73 +21.702 +67.963 +330.26 +135.12 +75.358 +329.75 +213.26 +188.26 +198.99 +64.303 +75.372 +47.043 +56.7 +0.032864 +0.29714 +1.2298 +0.13757 +0.43475 +0.17595 +0.20137 +0.32128 +0.013389 +0.067862 +0.076756 +0.0317 +0.008228 +0.026471 +0.065689 +0.084098 +0.020856 +108.99 +86.414 +21.645 +10.701 +114.78 +275.89 +59.646 +39.61 +30.829 +74.772 +1519 +233.41 +523.44 +182.64 +333.42 +103.08 +112.67 +156.47 +93.292 +161.39 +46.35 +53.415 +141.95 +93.537 +384.86 +79.639 +28.888 +48.559 +25.837 +23.973 +30.127 +25.532 +187.03 +189.41 +289.04 +406.55 +210.14 +606.31 +187.78 +47.317 +82.751 +0.23591 +0.1827 +0.036279 +0.14376 +0.18934 +0.13446 +0.16527 +0.4125 +0.46207 +0.34286 +0.021036 +0.032588 +0.12984 +0.038536 +0.014503 +0.013669 +0.071847 +0.14763 +0.14067 +90.213 +65.786 +15.323 +7.8638 +65.005 +306.02 +47.255 +681.07 +1381.9 +351.98 +609.14 +100.44 +312.94 +193.92 +265.78 +138.72 +154.29 +101.86 +70.404 +457.99 +81.21 +172.72 +137.15 +127.15 +260.87 +49.476 +44.337 +79.109 +98.754 +24.538 +17.166 +293.03 +160.9 +458.07 +274.75 +165.74 +188.53 +320.87 +140.04 +51.183 +1.2868 +0.49845 +0.069229 +0.068235 +0.023328 +0.14641 +0.55429 +0.32456 +0.11474 +0.18441 +0.037657 +0.033751 +0.046685 +0.052535 +0.43469 +0.091557 +0.053914 +0.12411 +0.26058 +0.044777 +57.603 +39.499 +18.982 +23.733 +427.31 +876.15 +463.67 +1407.7 +853.21 +730.83 +330.03 +72.821 +112.34 +173.86 +193.12 +8.4912 +8.216 +11.125 +183.18 +505.43 +13.04 +75.922 +145.12 +70.374 +165.03 +85.525 +0.03948 +0.063966 +51.063 +33.086 +16.826 +817.65 +290.85 +646.82 +213.6 +303.6 +161.68 +255.62 +0.6356 +0.17687 +0.94067 +0.55357 +0.16547 +0.062933 +0.061666 +0.011768 +0.049334 +0.10235 +0.032313 +0.18103 +0.056532 +0.17429 +0.091581 +0.16587 +0.11756 +1.0874 +0.31652 +0.22127 +0.070532 +0.033851 +57.026 +23.962 +1257.1 +1294.5 +626.19 +498.79 +287.61 +1541.1 +794.01 +508.54 +268.58 +147.68 +230.31 +75.688 +49.627 +6.2095 +217.31 +1197.9 +321.83 +191.44 +14.379 +79.972 +97.126 +136.82 +0.021514 +0.007827 +20.047 +0.053468 +41.131 +51.024 +1131.7 +902.49 +339.53 +1130.6 +302.85 +378.92 +145.17 +0.057038 +0.19252 +0.48657 +0.90054 +0.38425 +0.38058 +0.12796 +0.16751 +0.031015 +0.063999 +0.082118 +0.1279 +0.01472 +0.22981 +0.40355 +0.62896 +0.10493 +0.22375 +0.41069 +0.15286 +0.053713 +0.43361 +0.060175 +104.99 +14.189 +1179.7 +1157.6 +622.49 +753.82 +221.04 +1166.6 +955.65 +193.41 +287.64 +994.52 +114.24 +87.471 +35.783 +186.41 +359.33 +511.98 +160.38 +104.18 +32.682 +117.91 +270.65 +0.03439 +0.00761 +0.036021 +0.054414 +0.055327 +1908.1 +733.07 +902.34 +1231.9 +862.63 +832.6 +193.6 +281.07 +216.62 +0.055577 +0.055177 +0.1469 +0.11132 +0.62654 +0.35621 +0.084066 +0.12204 +0.54041 +0.026394 +0.063307 +0.01806 +0.069225 +0.21656 +0.38735 +0.16511 +0.044637 +0.14374 +0.44954 +0.40793 +0.022452 +0.022494 +0.017912 +204.88 +192.87 +219.84 +1139.2 +799.04 +585.47 +169.12 +944.73 +1292 +648 +2201.8 +532.67 +157.91 +60.103 +765.2 +288.78 +37.104 +41.414 +214.75 +68.606 +36.105 +1728.9 +0.087427 +0.091913 +0.14966 +0.24793 +0.097395 +0.15154 +1643.4 +1339 +507.75 +988.36 +14.16 +6.465 +67.495 +278.63 +608.36 +20000 +0.29726 +0.081376 +0.13631 +0.15145 +0.24469 +0.078288 +0.21849 +0.25451 +0.10246 +0.042455 +0.009998 +0.43855 +0.1858 +0.23549 +0.28397 +0.034734 +0.56939 +0.065779 +0.2423 +0.022365 +0.037905 +0.064475 +152.41 +183.65 +179.18 +484.45 +976.5 +598.33 +368.57 +687.21 +2370.9 +358.39 +1192.2 +397.32 +240.24 +136.75 +114.15 +27.8 +50.863 +42.337 +302.4 +381.22 +292.89 +3380.7 +0.4495 +0.37642 +0.47346 +0.40705 +38.559 +24.115 +7.0979 +20.524 +8.2543 +579.13 +441 +7.0297 +463.65 +149.05 +914.35 +11424 +5306.7 +0.065776 +0.083743 +0.17129 +0.12881 +0.098865 +0.099205 +0.36675 +0.076694 +0.050893 +0.10022 +0.22813 +0.19426 +0.054389 +0.052722 +0.052901 +0.15553 +0.10725 +0.16306 +0.36958 +0.23806 +0.23328 +128.38 +271.95 +268.3 +460.67 +926.67 +609.86 +576.22 +777.15 +2205.7 +845.24 +186.52 +343.57 +70.418 +87.967 +64.561 +16.164 +30.278 +3450.5 +254.44 +515.36 +466.31 +1601.7 +0.062995 +198.11 +63.856 +8.2241 +28.476 +37.953 +67.873 +38.098 +15.502 +14.066 +390.38 +9.3938 +14.959 +264.15 +330.88 +4883.9 +6483.2 +0.027342 +0.080711 +0.26539 +0.14223 +0.036764 +0.068373 +0.086826 +0.061436 +0.09274 +0.11073 +0.034654 +0.053774 +0.058785 +0.04813 +0.068237 +0.045184 +0.05324 +0.15088 +0.45824 +0.064929 +0.56958 +153.19 +474.61 +285.46 +548.46 +429.69 +752.81 +222.22 +1052.4 +1125.2 +1019.4 +301.31 +318.53 +40.414 +61.805 +47.064 +19.572 +2912 +2965.7 +1285 +1100 +368.53 +1106.3 +1524.8 +3244.8 +18.927 +11.331 +11.707 +40.729 +108.74 +25.58 +35.538 +15.585 +403.6 +79.298 +10.801 +26.854 +1.0501 +2549.3 +9614.1 +1000.4 +0.014624 +0.12442 +0.046415 +0.11215 +0.061612 +0.045251 +0.003685 +0.050648 +0.08627 +0.27103 +0.12599 +0.033378 +0.14017 +0.069181 +0.03481 +0.072204 +0.032787 +0.28272 +0.34053 +1.5226 +204.37 +3370 +959.85 +695.88 +580.35 +361.46 +701.47 +240.6 +353.84 +84.332 +196.92 +434.97 +23.003 +33.641 +27.741 +17.255 +5490.5 +5361.9 +5047.3 +1393.5 +957.77 +2251 +2576.6 +8013.5 +18.239 +16.713 +23.37 +35.998 +93.786 +47.002 +45.523 +449.01 +501.89 +17.411 +13.378 +23.224 +8.6063 +0.36344 +7010.9 +768 +1165.5 +0.20792 +0.14701 +0.096241 +0.22517 +0.070283 +0.016705 +0.040251 +0.017631 +0.13341 +0.049896 +0.25569 +0.23034 +0.12899 +0.064062 +0.034764 +0.028653 +0.25073 +0.31567 +1.0596 +345.68 +592.28 +2134.2 +1202.9 +539.47 +330.7 +409.63 +1199.2 +668.86 +124.53 +101.03 +15.569 +146.77 +32.936 +52.947 +13.684 +38.817 +5523.1 +5910.9 +558.18 +781.59 +5226 +5629.1 +7637.8 +7.106 +13.787 +34.437 +19.076 +35.607 +43.835 +56.498 +306.37 +372.91 +41.495 +21.882 +11.719 +9.6909 +0.40136 +0.1059 +841.57 +938.07 +487.94 +0.010238 +0.10553 +0.046506 +0.11898 +0.062395 +0.074887 +0.037402 +0.041439 +0.085629 +0.12357 +0.48259 +0.05641 +0.02809 +0.008891 +0.078475 +0.35253 +0.59843 +0.30841 +146.21 +95.998 +674.8 +1106.9 +441.7 +156.68 +447.74 +203.49 +320.22 +42.279 +114.12 +17.376 +116.68 +25.078 +60.922 +36.217 +45.414 +88.563 +6366.7 +491.95 +1182.1 +6178.2 +4796.2 +4481.3 +0.20407 +11.856 +21.926 +16.243 +23.729 +0.093971 +61.36 +361.93 +277.8 +46.069 +13.812 +16.442 +18.608 +4.5053 +0.034962 +0.063652 +1385.7 +386.44 +246.84 +0.14137 +0.45911 +0.34995 +0.26907 +0.36218 +0.19126 +0.1741 +0.022072 +0.16994 +0.038305 +0.050812 +0.069623 +0.006206 +0.021296 +0.292 +0.34715 +1.0713 +112.36 +43.416 +190.52 +686.82 +413.38 +220.37 +834.74 +748.82 +253.5 +57.745 +150.11 +21.212 +125.76 +36.243 +80.544 +84.903 +47.81 +51.836 +4049.5 +490.62 +194.32 +170.38 +5763.9 +4597.6 +0.90267 +0.86948 +0.81293 +0.25663 +0.2 +0.26418 +79.064 +141.85 +153.54 +35.027 +9.3936 +9.1993 +7.5821 +5.5996 +20.028 +0.044108 +0.11056 +240.89 +200.69 +123 +3.858 +3.0067 +0.40047 +0.25624 +0.61325 +0.57434 +0.35709 +0.11586 +0.034646 +0.02964 +0.068849 +0.014857 +0.005365 +0.35297 +0.50582 +1.1016 +113.23 +42.231 +111.29 +474.44 +468.83 +138.11 +277.49 +864.62 +201.23 +42.901 +62.746 +12.645 +115.77 +56.018 +53.807 +98.567 +70.706 +51.033 +24.592 +24.543 +210.43 +311.09 +80.96 +1853.7 +1440.3 +0.54587 +0.83071 +0.06988 +0.051265 +0.082991 +112.97 +320.2 +941.72 +2241.3 +19.074 +6.5456 +4.8211 +14.334 +6.48 +0.065746 +0.1132 +161.3 +61.142 +35.962 +13.512 +0.32989 +0.2049 +0.17805 +0.56547 +0.4957 +0.37138 +0.053374 +0.063802 +0.2806 +0.061452 +0.33847 +0.034291 +0.23814 +0.39771 +0.21901 +202.85 +43.508 +169.32 +52.427 +532.14 +1187.8 +233.47 +1208.8 +1634.6 +27.691 +38.937 +14.39 +7.947 +108.84 +68 +180.3 +106.66 +98.757 +25.396 +26.562 +52.594 +446.93 +75.141 +1957.7 +1161.5 +0.23214 +0.07412 +0.024165 +0.26018 +534.5 +116.63 +253.85 +190.13 +1612.9 +2283.9 +4.503 +4.6024 +10.57 +7.8631 +0.036369 +0.096908 +170.91 +53.093 +24.879 +27.583 +0.9919 +0.32218 +0.13575 +0.76685 +0.55023 +0.15789 +0.1557 +0.19741 +0.27046 +0.17342 +0.32438 +0.41117 +0.53851 +0.18219 +0.12775 +258.79 +76.91 +70.134 +83.549 +435.83 +103.45 +227.57 +1113.3 +1388 +655.59 +2554.8 +8.1038 +84.266 +232.55 +67.19 +153.73 +125.53 +431.86 +421.9 +23.984 +82.514 +49.544 +64.313 +83.672 +0.14088 +0.18529 +0.31038 +0.10529 +0.046473 +105.35 +76.261 +176.49 +137.31 +906.64 +1079.8 +287.75 +5.4632 +8.6178 +8.0025 +0.057809 +0.26716 +185.3 +35.779 +29.912 +51.068 +3.3967 +0.2249 +0.13473 +0.48103 +2.0001 +0.40828 +0.50174 +0.20536 +1.2002 +0.54592 +0.073546 +0.13058 +0.087965 +0.17538 +0.051666 +11951 +571.83 +65.441 +83.139 +100.29 +254.07 +481.44 +423.91 +313.72 +1852.2 +1201.8 +2723 +149.5 +281.99 +109.16 +119.64 +178.39 +32.871 +133.76 +202.18 +142.37 +91.291 +49.243 +67.492 +0.23922 +0.072452 +0.059104 +53.378 +81.514 +62.733 +69.171 +178.6 +78.902 +881.99 +789.59 +229.26 +345.68 +0.33845 +0.169 +0.65015 +653.95 +115.03 +40.762 +28.143 +18.116 +0.056281 +0.074211 +0.063786 +0.22665 +1.1135 +1.8627 +1.0306 +0.46698 +0.32024 +0.36744 +0.30865 +0.68378 +0.054778 +0.022752 +0.098575 +695.26 +314.55 +48.36 +116.48 +120.29 +758.04 +492.65 +387.25 +802.26 +364.69 +362.89 +2585 +1731.8 +813.71 +164.31 +118.89 +270.48 +47.187 +138.89 +257.83 +334.57 +185.02 +35.568 +65.29 +91.223 +74.021 +58.67 +89.157 +42.217 +144.56 +116.89 +382.92 +178.73 +1253.8 +413.14 +328.28 +191.12 +124.56 +66.652 +221.72 +485.79 +142.67 +22.968 +50.586 +0.065482 +0.096258 +0.07727 +0.45136 +0.7232 +0.50779 +0.35879 +1.3405 +0.9348 +0.25919 +0.31328 +0.30467 +0.11207 +0.078028 +0.092702 +0.044516 +3911.3 +117.63 +47.884 +44.938 +153.72 +631.03 +409.18 +363.28 +406.72 +1529.7 +1943.4 +752.7 +2317.6 +1037.6 +205.51 +175.65 +215.92 +410.92 +136.63 +40.846 +10.936 +0.035188 +0.037047 +94.905 +79.32 +76.547 +28.58 +97.661 +90.744 +341.78 +915.11 +463.13 +203.47 +1214.2 +187.42 +93.426 +102.97 +247.47 +122.24 +379.72 +949.23 +184.88 +34.48 +0.14067 +0.16036 +0.32147 +0.55511 +1.6732 +1.485 +0.30166 +0.35656 +0.87711 +1.5999 +1.2133 +0.071639 +0.097078 +0.062833 +0.078319 +0.11189 +0.052087 +75.47 +327.33 +810.94 +48.94 +112.36 +135.99 +564.03 +428.81 +325.42 +943.08 +1018.4 +446.23 +115.62 +1086.5 +84.748 +333.55 +335.2 +170.43 +90.889 +30.856 +18.218 +0.08446 +289.18 +35.908 +116.06 +150.16 +50.736 +87.845 +84.283 +686.2 +1359.7 +1156.3 +5158.4 +0.03407 +0.012671 +33.992 +0.16328 +0.23849 +0.10527 +0.19088 +0.14316 +0.049323 +0.25146 +0.13173 +0.05233 +0.29288 +3.2381 +1.7772 +1.2188 +0.30211 +0.45187 +0.81733 +0.95902 +0.82853 +0.13628 +0.24409 +0.073842 +0.071618 +0.091826 +0.007311 +56.215 +191.47 +864.48 +130.37 +81.244 +94.073 +450.03 +246.6 +80.84 +431.87 +546.67 +590.07 +120.21 +112.54 +123.52 +283.8 +398.25 +75.39 +81.79 +55.74 +0.080217 +0.18078 +72.451 +16.982 +90.54 +162.77 +33.063 +488.43 +174.03 +1234.7 +1039.1 +42.749 +274.46 +0.019462 +0.12007 +0.19701 +0.27779 +0.19921 +0.31658 +0.19006 +0.20798 +0.14864 +0.30309 +0.18967 +0.12345 +0.19997 +0.16787 +0.24989 +0.099583 +0.51502 +0.28993 +0.28413 +0.60542 +0.1241 +0.11731 +0.16837 +0.093039 +0.056192 +0.078605 +0.18962 +55.558 +30.342 +1549.3 +189.7 +89.231 +140.53 +480.34 +598.94 +109.5 +266.7 +378.21 +548.59 +412.09 +145.58 +94.823 +363.46 +287.54 +64.579 +48.83 +79.264 +54.063 +29.332 +41.572 +14.703 +134.29 +177.88 +41.869 +419.71 +197.37 +385.14 +1603.4 +16.175 +0.23558 +0.047942 +0.057576 +0.54416 +0.48425 +0.30715 +0.70684 +0.27651 +0.29715 +0.20019 +0.1284 +0.43112 +0.1543 +0.10444 +0.086 +0.78884 +0.31419 +0.38494 +0.57546 +5.5527 +0.67306 +0.28949 +0.032038 +0.25226 +0.12284 +0.093856 +0.12448 +0.37224 +132.87 +61.206 +1156.4 +232.62 +124.87 +109.49 +347.17 +358.27 +209.4 +177.35 +436.02 +421.17 +378.35 +402.46 +346.72 +180.53 +83.654 +64.524 +78.777 +229.11 +72.587 +29.299 +38.82 +179.89 +221.37 +407.22 +3216.7 +3847.9 +73.903 +30.069 +69.121 +20.66 +0.31024 +2.3437 +0.28557 +0.2806 +0.52248 +0.55234 +1.6657 +0.10042 +0.20653 +0.44536 +0.2626 +0.12362 +0.021098 +0.009823 +0.066443 +0.15849 +0.035409 +0.020897 +0.38456 +1.5403 +1.7864 +0.92947 +0.1211 +0.18169 +0.03437 +0.068512 +0.0726 +0.063071 +127.7 +102.22 +41.982 +143.75 +132.75 +75.615 +202.33 +306.12 +238.7 +208.67 +423.31 +827.72 +818.41 +633.15 +892.4 +165.11 +94.909 +106.2 +179.32 +471.13 +53.886 +104.46 +30.052 +303.97 +175.25 +384.58 +83.087 +3380.1 +62.574 +46.787 +130.47 +1.6314 +1.4338 +0.68098 +0.23397 +0.28988 +0.36032 +0.12572 +0.55654 +0.33438 +0.086464 +0.14357 +0.088183 +0.030601 +0.01347 +0.030183 +0.068391 +0.06299 +0.16731 +0.11754 +0.19204 +0.10179 +0.48884 +0.83021 +0.15179 +0.11309 +0.15335 +0.051284 +0.11109 +0.26902 +130.47 +111.1 +39.982 +324.16 +212.63 +80.125 +92.203 +198.71 +146.07 +139.22 +61.682 +2072.5 +1101.5 +1160.8 +2828.3 +2712.6 +144.74 +197.01 +317.23 +254.66 +614.69 +46.991 +276.81 +240.28 +421.74 +174.91 +123.19 +47.067 +30.73 +27.222 +0.79767 +0.93031 +0.6527 +0.18686 +0.57061 +0.16706 +0.39984 +0.35152 +0.18556 +0.26583 +0.35237 +0.091806 +0.032438 +0.030631 +0.025176 +0.026231 +0.24591 +1.3939 +0.51838 +0.32738 +0.16568 +0.097878 +0.25571 +0.86376 +0.17641 +0.033889 +0.014991 +0.026878 +0.087333 +0.16469 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/layer84_permz.geos b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/layer84_permz.geos new file mode 100644 index 00000000000..fb4bb7c6d70 --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/layer84_permz.geos @@ -0,0 +1,13200 @@ +6.4542e-06 +3.4083e-06 +3.3865e-06 +0.0012584 +0.0025506 +0.0049557 +0.011005 +0.94973 +0.18647 +0.055489 +0.077892 +0.016698 +0.11529 +0.043023 +0.094006 +0.034537 +0.022937 +117.11 +223.44 +33.238 +56.975 +0.0061175 +0.0045341 +0.02993 +0.026893 +0.0051619 +0.0025665 +0.011614 +1.0857e-05 +3.0584e-05 +1.1793e-05 +9.7815e-06 +1.8215e-05 +1.3971e-05 +9.1116e-06 +4.6364e-06 +1.0297e-05 +7.9578e-06 +1.3536e-06 +3.645e-06 +1.0576e-05 +4.5575e-05 +1.9143e-05 +8.1675e-06 +0.052147 +0.058883 +0.042518 +0.0060599 +0.0071636 +0.028538 +0.036131 +0.0017056 +0.0047555 +0.014849 +0.0065429 +0.0034798 +0.011185 +0.013638 +0.0098327 +50.995 +1.1286e-05 +1.0634e-05 +8.1667e-06 +5.2393e-06 +0.0032541 +0.0036477 +0.016646 +0.22377 +0.067813 +0.049244 +0.079361 +0.028587 +490.01 +202.93 +0.037146 +0.042683 +0.037978 +110.97 +86.644 +20.79 +20.101 +0.0025327 +0.0039998 +0.037997 +0.025787 +0.0065124 +0.0028595 +0.0098913 +2.8881e-05 +3.3028e-05 +2.5872e-05 +1.233e-05 +4.8856e-06 +2.2513e-05 +3.7565e-05 +2.6637e-06 +5.9152e-06 +3.4875e-06 +1.443e-06 +1.9086e-06 +1.1767e-05 +9.9196e-06 +7.389e-06 +3.4775e-06 +0.043254 +0.0324 +0.0052078 +0.014262 +0.019534 +0.023121 +0.024673 +0.03173 +0.0061988 +19.557 +0.025883 +0.0034476 +0.013853 +0.027658 +0.016655 +87.986 +6.5883e-06 +9.7745e-06 +2.0938e-05 +7.9875e-05 +4.9302e-05 +2.3443e-05 +0.0044765 +0.020005 +0.060883 +0.019016 +0.056679 +0.023007 +0.09989 +0.064859 +0.01452 +0.061766 +0.057448 +102.28 +41.87 +21.954 +25.789 +0.0022285 +0.0047058 +0.012034 +0.023596 +0.0027214 +0.0024529 +0.0070773 +6.3261e-05 +1.8382e-05 +1.9455e-05 +1.2733e-05 +8.6306e-06 +1.5792e-05 +2.3827e-05 +3.8131e-05 +1.5722e-05 +2.4469e-05 +4.3473e-06 +1.2284e-05 +2.5926e-05 +8.7617e-06 +3.6858e-06 +5.5697e-06 +0.02466 +0.037672 +0.0087035 +0.025294 +0.033894 +0.014143 +0.03082 +0.023784 +0.004703 +27.017 +0.014126 +0.0038305 +0.04231 +0.02316 +0.014491 +58.056 +1.9582e-05 +2.9963e-06 +1.6623e-05 +1.8874e-05 +6.3653e-05 +1.3589e-05 +4.6928e-05 +6.9859e-06 +0.0084093 +0.029766 +0.070997 +0.033223 +353.8 +288.01 +0.0099835 +0.067955 +0.069079 +0.023029 +19.435 +22.489 +19.191 +0.0029326 +0.0031055 +0.0062858 +0.0078211 +0.0049509 +0.0027538 +0.00523 +1.4683e-05 +7.3425e-06 +7.9791e-06 +2.3118e-05 +1.5686e-05 +3.7766e-05 +2.3192e-05 +1.8254e-05 +1.3246e-05 +3.6985e-05 +2.8115e-05 +4.5961e-05 +2.039e-05 +1.4442e-05 +1.2089e-05 +3.5193e-06 +0.0051816 +0.027909 +0.009852 +0.016548 +0.020567 +0.0084122 +0.012641 +0.014461 +0.014112 +25.336 +29.621 +0.0029542 +0.0030702 +0.0032005 +0.0064901 +57.245 +2.4328e-05 +4.5128e-06 +2.7136e-05 +1.7964e-05 +2.8686e-05 +3.1372e-05 +1.0345e-05 +2.7707e-06 +0.0065548 +0.019202 +0.10566 +0.045114 +170.57 +0.088424 +43.184 +65.588 +0.035426 +0.022368 +0.018213 +22.095 +3.7483 +0.002324 +0.0024469 +0.012055 +0.008703 +0.0059859 +0.0063365 +0.0057563 +0.020547 +1.0258e-05 +3.6084e-06 +2.2701e-05 +3.4276e-05 +1.5466e-05 +3.7823e-06 +4.2638e-06 +4.1338e-05 +3.1336e-05 +0.00010557 +7.4098e-06 +1.2464e-05 +6.3393e-06 +1.5805e-05 +7.1952e-06 +1.078e-05 +0.016137 +0.010825 +0.028925 +0.012291 +0.020505 +0.048329 +0.008651 +11.551 +14.808 +10.408 +0.002144 +66.711 +102.15 +10.64 +114.82 +1.7405e-05 +2.4344e-05 +2.1956e-05 +1.1204e-05 +5.0225e-05 +4.0387e-05 +1.3347e-05 +0.0044621 +0.0049595 +0.020514 +0.011097 +0.023158 +179.42 +0.024189 +0.012755 +77.305 +90.436 +79.243 +0.020578 +283.76 +0.040689 +0.0033532 +0.0088773 +0.013935 +0.0043266 +0.0031504 +0.0050983 +0.0070095 +0.011672 +1.2884e-06 +2.1406e-06 +1.1139e-05 +1.3991e-05 +2.3014e-05 +8.3808e-06 +1.4631e-05 +4.154e-05 +3.9946e-05 +5.8834e-05 +1.0903e-05 +2.3152e-06 +6.2313e-06 +4.4326e-05 +4.2737e-06 +1.1187e-05 +2.0606e-05 +250.02 +0.02002 +0.018546 +0.013976 +0.043392 +0.011596 +13.198 +17.546 +0.003838 +0.0015999 +42.677 +81.733 +37.719 +112.2 +3.6356e-05 +2.3023e-05 +3.4597e-05 +5.7646e-05 +6.9528e-05 +1.8271e-05 +0.0012786 +0.002228 +0.0072075 +0.029326 +0.0069144 +0.014489 +0.018507 +0.0065641 +0.022753 +20.905 +33.669 +49.178 +0.011052 +167.23 +124.32 +0.0044922 +0.0090015 +0.02186 +0.0032666 +0.0031722 +0.0028023 +0.0082649 +0.0082842 +2.781e-05 +1.5826e-05 +2.424e-05 +2.6436e-05 +7.9702e-06 +6.8927e-06 +1.803e-05 +2.2496e-05 +3.0583e-05 +9.2788e-05 +1.3457e-05 +1.1549e-06 +7.2593e-06 +2.6906e-05 +1.108e-05 +0.10054 +121.09 +107.26 +53.744 +0.022794 +0.016922 +0.024856 +76.964 +40.729 +0.0046386 +26.186 +24.197 +80.474 +33.168 +21.156 +106.42 +1.7062e-05 +1.9122e-05 +0.00014683 +2.8591e-05 +0.00011344 +6.1433e-05 +0.001497 +0.0031062 +0.0070954 +0.023254 +0.017912 +0.012054 +40.081 +0.0089496 +15.844 +113.94 +60.247 +30.255 +0.0075243 +47.301 +0.034774 +0.02061 +68.797 +0.011401 +0.0020654 +0.0033827 +0.0040613 +0.0076305 +0.0022376 +0.0063505 +1.1355e-05 +1.4114e-05 +1.1373e-06 +5.7265e-06 +2.0587e-05 +2.1325e-05 +5.5662e-06 +9.3884e-06 +1.4534e-05 +4.8081e-06 +4.1314e-06 +4.6246e-06 +3.562e-06 +0.076017 +365.09 +223.78 +238.75 +29.974 +0.020406 +0.012377 +75.929 +0.020419 +0.015204 +0.013802 +25.463 +24.786 +31.447 +23.069 +17.862 +45.732 +2.9373e-05 +1.3717e-05 +2.9431e-05 +0.00043611 +3.2076e-05 +8.3081e-05 +0.0027533 +0.0064722 +0.0031243 +0.01778 +0.021194 +0.015824 +20.78 +17.021 +92.294 +101.81 +77.178 +18.17 +0.0076742 +50.767 +0.044462 +0.020819 +0.037292 +26.721 +10.382 +0.0036319 +0.0027375 +0.010642 +0.0024527 +0.0075613 +0.23629 +7.2295e-06 +3.3354e-06 +1.8601e-06 +8.9319e-06 +8.6002e-06 +6.6354e-06 +1.7864e-05 +3.2434e-05 +6.6334e-06 +6.1923e-06 +1.465e-05 +2.0517e-05 +0.045933 +133.23 +210 +230.58 +29.976 +0.017093 +0.023383 +0.13894 +113.35 +0.023573 +0.025135 +31.244 +19.437 +23.043 +1.625e-05 +2.4275e-05 +3.0701e-06 +4.5119e-05 +2.0232e-05 +5.466e-05 +6.5022e-05 +5.5413e-05 +1.0716e-05 +0.004639 +0.008323 +0.0037374 +0.021388 +15.566 +6.8933 +22.36 +50.617 +56.32 +70.494 +69.684 +9.2923 +0.029442 +170.07 +0.052952 +73.596 +0.031332 +0.025705 +0.038516 +0.015747 +0.012916 +0.013572 +0.0027896 +0.0078059 +0.32422 +0.097566 +7.2112e-06 +2.9737e-06 +6.779e-06 +3.5362e-06 +8.3346e-06 +2.2955e-05 +7.1457e-06 +1.2459e-05 +1.1444e-05 +0.31724 +83.695 +0.058988 +175.36 +120.98 +225.27 +0.021759 +0.019454 +0.016441 +0.046793 +0.13608 +0.029077 +75.922 +0.035559 +0.01964 +0.032685 +1.4956e-05 +1.1366e-05 +1.5315e-05 +3.7969e-05 +2.3949e-05 +1.0672e-05 +7.9027e-06 +8.0941e-06 +6.4121e-06 +0.0072658 +0.0043561 +15.245 +0.013724 +7.6659 +0.0016117 +15.91 +104.18 +60.491 +89.769 +52.963 +10.163 +0.046213 +0.013641 +0.011291 +0.013866 +0.022194 +0.018874 +0.080349 +0.011676 +0.091263 +0.012761 +0.012575 +0.016611 +0.010156 +0.091179 +0.018647 +8.453e-06 +3.9313e-06 +4.9767e-06 +4.0395e-05 +1.0691e-05 +1.6847e-06 +0.016196 +0.057741 +0.20997 +0.024199 +95.735 +0.22616 +0.24421 +0.020918 +0.014651 +0.015946 +0.034849 +0.026367 +138.87 +0.01299 +32.123 +39.926 +0.07113 +0.02754 +5.5833e-06 +1.4019e-05 +6.268e-06 +2.0509e-05 +2.143e-05 +2.5294e-05 +5.2994e-05 +7.9145e-06 +9.0655e-06 +0.0047828 +8.0254 +9.5821 +0.0055881 +51.814 +9.3075 +0.008353 +141.74 +142.06 +54.175 +20.407 +5.4557 +0.05138 +0.0087376 +0.0062507 +0.017249 +0.02682 +0.021104 +0.037153 +0.004153 +0.0079049 +0.053362 +0.021818 +0.0033722 +0.014907 +0.0076799 +0.050542 +2.8038e-06 +1.2757e-05 +9.8478e-06 +4.0759e-05 +2.3775e-05 +0.03523 +0.036197 +0.050775 +0.1063 +0.046321 +0.09346 +0.18002 +0.24415 +0.016196 +0.0071926 +0.012974 +83.038 +225.78 +111.97 +16.769 +66.728 +80.289 +0.0855 +0.054759 +0.075428 +1.2624e-05 +5.6341e-06 +9.1799e-06 +1.8029e-05 +5.4194e-05 +1.7822e-05 +2.4298e-05 +2.2995e-05 +0.011558 +16.729 +0.0051966 +0.006055 +25.165 +12.289 +33.44 +0.043703 +187.61 +18.258 +33.113 +10.529 +0.034429 +0.022848 +0.023204 +0.028452 +136.07 +0.022313 +0.045408 +0.0079732 +0.0078156 +0.032748 +0.026976 +0.092872 +0.03735 +0.0051307 +0.010701 +2.7685e-06 +4.9666e-06 +1.022e-05 +2.1973e-05 +0.0060967 +0.029113 +0.048285 +0.088998 +0.19865 +0.027988 +0.29715 +0.18875 +505.82 +0.017706 +73.799 +0.023977 +0.013389 +142.78 +149.43 +21.919 +45.145 +59.213 +0.1038 +0.082851 +5.4693e-06 +2.7247e-06 +4.2157e-06 +3.4732e-06 +1.816e-06 +1.158e-05 +2.2036e-05 +2.3251e-06 +4.1459e-06 +0.022457 +0.0076117 +0.0070432 +69.168 +17.18 +17.202 +79.183 +89.411 +160.71 +13.218 +71.401 +0.033579 +0.011585 +0.10133 +0.054753 +0.049085 +224.53 +0.019651 +0.023521 +0.0038992 +0.017413 +0.061447 +0.050834 +0.10931 +0.020776 +0.0076966 +0.23035 +0.64683 +1013.4 +1070.5 +0.023279 +0.010271 +0.015452 +0.029664 +0.066662 +4.4901e-06 +3.3646e-06 +7.4568e-06 +0.10408 +436.79 +145.35 +111.82 +0.016515 +0.011714 +0.0069967 +98.402 +123.38 +81.446 +0.29091 +0.13385 +1.0492e-05 +9.618e-06 +1.7501e-05 +4.2574e-06 +4.5451e-06 +3.2037e-06 +6.4184e-06 +1.3178e-05 +4.5783e-06 +1.872e-05 +0.038062 +0.011271 +0.0086495 +75.031 +23.711 +27.097 +66.173 +98.692 +43.807 +10.053 +0.042875 +38.815 +0.013141 +0.014174 +0.051804 +195.65 +247.32 +0.022494 +0.04559 +0.090334 +0.036835 +0.074147 +0.039417 +0.082535 +0.071921 +0.012673 +0.0053909 +0.16822 +1176.2 +1601.3 +2168.1 +0.0063056 +0.01963 +0.020731 +1.8731e-06 +8.1244e-06 +3.119e-06 +3.4039e-06 +0.1053 +376.91 +137.27 +214.24 +63.241 +0.043648 +0.0071696 +54.988 +0.030312 +207.34 +140.36 +4.3608e-06 +5.7146e-06 +3.4246e-05 +1.3845e-05 +5.0325e-06 +1.0604e-05 +2.2569e-06 +1.0474e-05 +1.7147e-05 +2.6691e-05 +6.6749e-05 +0.037588 +0.0096477 +0.018603 +76.707 +27.976 +16.733 +32.809 +38.861 +35.252 +9.0337 +0.070212 +46.084 +0.021721 +0.24003 +0.039082 +0.052863 +203.63 +50.927 +0.090257 +0.078616 +0.058342 +0.15554 +0.027307 +0.079645 +0.069255 +0.015724 +0.0064409 +0.06938 +0.19535 +1303.5 +1472.7 +2058.5 +0.011513 +0.019653 +1.0065e-06 +5.226e-07 +1.5142e-06 +4.4592e-06 +252.5 +210.45 +0.056997 +421.24 +126 +283.51 +0.0091569 +0.03727 +143.87 +260.36 +1.4671e-05 +2.2754e-06 +5.8072e-06 +2.5578e-05 +3.73e-05 +1.2615e-05 +1.0488e-05 +4.0757e-06 +3.8922e-06 +1.141e-05 +0.00015126 +0.00052666 +5.0732e-05 +0.0001732 +0.0057488 +0.016249 +33.586 +32.845 +44.006 +60.994 +18.201 +7.2348 +24.933 +81.304 +0.0083895 +0.11658 +0.050666 +0.070471 +161.13 +67.914 +0.048678 +0.085098 +0.07925 +66.559 +0.0097752 +86.34 +0.05064 +0.02597 +0.0063292 +0.025946 +0.028167 +1378.3 +893.24 +1778.9 +0.015472 +1.8093e-05 +2.3153e-06 +1.3063e-06 +6.2635e-06 +440.52 +28.2 +296.51 +0.11462 +0.10075 +189.31 +469.06 +0.055579 +0.037358 +269.34 +153.04 +0.00015394 +7.1805e-06 +4.1543e-05 +2.2775e-05 +1.6103e-05 +1.4905e-05 +3.836e-05 +5.9474e-06 +6.8608e-06 +3.7691e-05 +5.6713e-05 +0.00044797 +2.1819e-05 +6.5353e-06 +0.0045733 +0.0083197 +0.015454 +0.0098953 +13.37 +30.152 +10.922 +11.6 +32.204 +8.0292 +11.075 +0.069139 +0.042364 +0.050346 +63.38 +119.44 +32.779 +0.093374 +0.066461 +0.024523 +0.00971 +273.41 +0.079412 +0.023475 +0.010176 +0.0094315 +0.029258 +0.082585 +677.19 +542.9 +0.0065881 +0.00012157 +2.0488e-05 +4.1237e-06 +5.5386e-06 +2.2325e-05 +75.708 +0.012301 +0.30591 +115.12 +65.876 +138.28 +0.10394 +0.03523 +0.01279 +5.7797e-06 +6.0867e-05 +1.5544e-05 +2.1043e-05 +2.5787e-05 +2.688e-05 +2.0647e-05 +5.459e-05 +7.2486e-06 +4.1144e-06 +6.1576e-06 +3.7612e-05 +2.2198e-05 +6.1339e-06 +1.8407e-06 +0.0077257 +0.013734 +0.019979 +0.0093143 +20.944 +29.224 +12.565 +9.1943 +12.516 +0.0051445 +201.06 +0.042182 +0.032757 +0.076136 +75.101 +81.426 +38.514 +0.02309 +0.0086811 +0.01777 +4.6207e-06 +425.13 +0.044781 +0.035922 +0.022509 +0.0085249 +0.039868 +0.14506 +472.06 +0.32035 +0.23039 +8.5812e-06 +1.2855e-05 +5.8119e-06 +5.8183e-06 +24.848 +101.44 +7.3316 +105.57 +180.17 +0.037171 +86.407 +233.22 +0.012696 +0.013574 +224.51 +2.8827e-05 +9.2401e-05 +9.9892e-06 +6.3414e-06 +4.7237e-06 +2.3694e-05 +1.953e-05 +1.6815e-06 +6.2956e-06 +1.0603e-05 +2.0299e-05 +6.8023e-06 +1.5586e-06 +7.9782e-06 +6.9472e-06 +0.00709 +0.01688 +24.901 +19.869 +26.817 +11.72 +3.5711 +10.036 +44.565 +0.068931 +153.12 +0.025516 +0.03969 +69.904 +70.409 +44.468 +0.019256 +0.013209 +0.037794 +2 +192.33 +0.053518 +0.042213 +0.02037 +0.010314 +0.016408 +0.038422 +0.35952 +0.33266 +4.3644e-05 +8.7682e-05 +2.1329e-05 +0.021608 +20.36 +26.468 +99.75 +12.097 +22.776 +0.057144 +0.068147 +0.070388 +225.58 +0.0096307 +16.51 +245.1 +257.36 +0.00018641 +3.0399e-05 +2.3181e-06 +9.5362e-06 +8.5263e-06 +2.839e-06 +6.9068e-06 +4.5199e-06 +7.7594e-06 +1.4852e-05 +8.044e-06 +4.5626e-06 +2.9042e-06 +6.2378e-06 +0.003899 +29.115 +37.701 +38.926 +54.623 +13.707 +17.429 +0.047137 +0.0087832 +0.040789 +155.82 +0.027096 +0.049063 +113.93 +78.173 +70.763 +1367.7 +0.010119 +66.044 +2 +54.928 +147.53 +0.07849 +0.019265 +0.026635 +0.032163 +0.026047 +1184.3 +1.5472e-05 +1.247e-05 +8.6955e-06 +1.5395e-05 +0.0017211 +59.305 +27.725 +130.27 +0.0030135 +56.696 +114.44 +945.33 +344.19 +66.637 +0.017138 +2.386 +167.71 +182.61 +0.028197 +2.2344e-05 +8.2356e-06 +5.2349e-06 +4.474e-06 +6.468e-07 +8.5523e-06 +5.5831e-06 +1.6622e-05 +7.1888e-06 +5.1486e-06 +1.0634e-06 +1.0723e-05 +28.46 +0.00341 +33.79 +24.51 +37.722 +30.677 +9.173 +0.032797 +0.034143 +0.0087525 +0.026253 +0.043291 +0.0077231 +117.46 +93.641 +73.856 +1195.9 +958.97 +0.039199 +75 +65.327 +59.849 +339.4 +0.032268 +0.029015 +0.02575 +0.037657 +3.2552e-05 +2.0756e-05 +4.1813e-05 +4.6419e-05 +4.2621e-05 +3.1134 +0.0015666 +0.0043303 +278.27 +220.71 +31.054 +44.953 +0.038174 +619.58 +0.01087 +0.015515 +0.0074238 +2.9237 +0.056477 +221.92 +95.667 +0.025418 +5.016e-06 +1.5938e-05 +4.4953e-05 +6.4601e-05 +2.1304e-06 +4.6599e-06 +3.7551e-06 +5.0755e-06 +4.9153e-06 +0.067011 +0.031338 +60.833 +0.0025987 +41.405 +0.0074498 +50.206 +0.089658 +0.047779 +0.06176 +0.018795 +0.0076598 +0.038653 +0.070547 +51.639 +0.044419 +152.64 +418.32 +747.55 +42.242 +109.09 +339.58 +0.040283 +37.687 +0.098979 +0.076808 +0.021783 +0.0093863 +7.3146e-06 +1.392e-05 +6.6525e-06 +6.4315e-06 +8.6e-06 +6.2137e-06 +3.304 +0.0011121 +0.0089623 +151.6 +68.108 +17.999 +53.958 +0.062313 +0.016734 +0.014528 +0.01063 +0.018374 +0.0023414 +0.035303 +0.034634 +35.5 +3.8989e-05 +4.8508e-06 +1.4228e-05 +5.9671e-06 +5.8192e-06 +1.5036e-05 +4.2229e-05 +2.2523e-05 +1.0655e-05 +1.7156e-05 +0.062991 +0.050561 +0.022795 +0.0055159 +0.014797 +0.0085203 +0.15981 +0.12437 +0.10363 +0.016831 +0.01419 +0.018092 +0.058224 +0.044222 +78.358 +92.785 +1615.3 +2.9577e-05 +0.014873 +0.0099551 +63.952 +220.75 +0.076704 +47.138 +0.0049371 +299.84 +140.21 +1.5842e-05 +3.1487e-06 +4.0931e-06 +2.0878e-05 +1.5259e-05 +3.3171e-05 +0.0011363 +2.4674 +0.00069178 +62.554 +71.536 +73.956 +37.487 +0.0057279 +0.010368 +0.013334 +0.015473 +0.019842 +0.060644 +14.998 +0.054356 +0.031061 +76.342 +9.4992e-06 +8.6519e-06 +1.2653e-05 +6.8546e-06 +9.167e-06 +4.7976e-06 +8.0055e-06 +1.8503e-05 +6.5935e-06 +0.043644 +0.038365 +0.017741 +0.018957 +0.0089964 +0.028968 +0.09752 +0.034099 +0.010923 +0.0051145 +0.016532 +0.00795 +0.022037 +0.11444 +0.056487 +1870 +0.032603 +0.025897 +0.0080484 +0.010437 +0.0070665 +0.017214 +182.22 +0.13154 +610.7 +0.041198 +0.095381 +3.7991e-06 +5.6282e-06 +3.9962e-06 +5.9559e-06 +1.805e-05 +2.7062e-05 +0.00014387 +1.3982 +41.638 +34.124 +0.0010047 +0.0015914 +18.261 +17.027 +0.0023284 +0.01449 +0.013317 +0.0242 +0.0076539 +0.036693 +0.006701 +0.043908 +0.060139 +87.829 +0.16792 +2.0646e-05 +9.0226e-06 +5.1762e-06 +1.6651e-05 +6.3797e-06 +3.858e-06 +5.3665e-06 +5.3837e-06 +0.034242 +0.035726 +1.4388e-05 +0.020749 +0.036489 +0.02439 +0.067755 +0.01779 +0.017202 +0.0039464 +0.014403 +0.016396 +0.010644 +2803.3 +2201.7 +0.013406 +0.028362 +0.069786 +0.010766 +0.011239 +0.017522 +187.96 +1.3755e-05 +297.84 +420.31 +0.04115 +0.084772 +0.18328 +2.6055e-05 +3.7582e-05 +8.1309e-06 +1.7563e-05 +1.2407e-05 +0.062501 +372.48 +0.0080451 +0.0017904 +0.0018647 +0.00068496 +0.00026433 +0.0084082 +0.0046953 +0.014448 +0.014576 +0.022934 +0.011221 +0.017566 +0.01334 +0.049373 +0.077702 +0.043879 +0.22234 +2.4289e-05 +9.0909e-06 +5.4286e-06 +3.5886e-06 +4.2054e-06 +1.7021e-06 +3.6003e-06 +3.3485e-06 +5.6762e-06 +0.071437 +0.011205 +0.030228 +0.082707 +0.029239 +0.045893 +0.036344 +0.017285 +0.010884 +0.025263 +0.023415 +3607.1 +0.010283 +0.013489 +0.025497 +0.05073 +0.069386 +0.023478 +67.256 +2.1142e-05 +1.5445e-05 +6.9956e-06 +148.44 +183.24 +186.76 +0.10291 +0.17721 +0.030151 +1.8088e-05 +1.2615e-05 +8.3816e-06 +0.03322 +4.5379e-06 +1.8357e-06 +2.4315e-06 +0.0014364 +4.4147 +2.246 +0.0058744 +0.0077545 +0.007997 +0.02235 +0.017129 +0.023606 +0.016315 +0.025584 +0.051673 +1.1899e-06 +0.071716 +0.029642 +0.21017 +0.073389 +1.2212e-06 +2.4235e-06 +2.7301e-06 +2.557e-06 +1.0744e-06 +2.4276e-06 +4.748e-06 +0.0094542 +0.0080874 +0.0099301 +0.030732 +0.086822 +0.068278 +0.043797 +0.048238 +0.037226 +0.030769 +0.003634 +0.015575 +0.0081583 +0.012778 +0.010665 +0.010124 +0.042424 +0.043357 +0.020287 +1.3553e-05 +2.0352e-06 +5.4023e-06 +3.7423e-06 +2.3142e-06 +111.86 +155.7 +0.052658 +0.083426 +0.029872 +0.009051 +179.33 +326.26 +2.6311e-06 +3.2221e-06 +6.7858e-06 +3.7855e-06 +6.7948e-06 +5.9987e-06 +0.010408 +0.0095129 +0.01477 +0.014352 +0.032302 +0.014859 +0.048715 +0.05964 +0.086381 +0.093784 +0.035545 +0.019874 +0.017955 +0.20365 +1.7805e-06 +2.7843e-06 +3.7913e-06 +3.9088e-06 +2.631e-06 +2.2821e-06 +0.023555 +0.011799 +0.004388 +0.0090053 +0.012931 +0.024962 +0.10788 +0.1344 +0.04969 +0.043009 +0.037478 +0.0029099 +0.0094298 +0.014363 +0.016217 +0.014208 +0.0071208 +0.0092798 +0.022248 +0.29873 +4.223e-06 +2.3116e-06 +1.6845e-05 +2.9541e-06 +4.3063e-06 +296.54 +83.087 +200.65 +0.03064 +0.072162 +0.038179 +0.081732 +630.01 +0.00078004 +2.9002e-06 +6.3596e-06 +3.2126e-06 +0.016494 +0.016656 +0.016223 +0.014435 +0.0091474 +0.010339 +0.0087628 +0.024426 +0.031917 +0.055378 +0.065483 +0.04618 +0.051182 +0.020813 +0.034031 +0.0392 +0.078686 +3.6235e-06 +8.0712e-06 +8.9838e-06 +1.6975e-05 +5.1504e-06 +0.022724 +0.014728 +0.0082719 +0.0023627 +0.0046817 +39.68 +0.018831 +0.086068 +0.057589 +0.028871 +0.07631 +22.124 +0.011637 +0.0096039 +0.016491 +0.0073634 +0.014424 +0.0070428 +0.0070998 +0.38152 +0.20414 +1.3388e-05 +1.3954e-05 +1.3916e-05 +2.3716e-06 +1.9203e-06 +276.38 +86.274 +237.21 +0.1085 +0.099812 +0.037165 +163.73 +410.32 +0.0011845 +1.1215e-06 +0.57478 +1.0258 +0.084105 +0.011753 +0.015313 +0.016942 +0.012066 +0.014486 +0.02851 +0.028917 +0.013082 +0.021767 +0.02058 +0.028847 +0.043223 +0.018183 +0.025183 +0.10772 +0.073678 +3.2814e-05 +6.4353e-06 +1.8512e-05 +4.1463e-06 +0.012027 +0.019009 +0.010656 +0.0093094 +0.0025747 +23.856 +0.019222 +0.023007 +0.11617 +0.055042 +0.034185 +53.223 +40.283 +0.017731 +0.01055 +0.016413 +0.012076 +0.0059415 +0.0040681 +0.0045245 +0.25685 +0.30293 +0.4473 +2562.6 +2.2298e-06 +3.5673e-06 +3.5346e-06 +293.25 +118.39 +274.16 +0.064609 +0.23714 +0.029766 +0.027983 +293.15 +0.012468 +3.1991e-06 +0.4585 +0.96695 +0.097054 +0.017193 +0.0084455 +0.021119 +489.01 +837.9 +0.046526 +0.014491 +0.014896 +0.014798 +0.013303 +0.041629 +0.032425 +0.011846 +0.02361 +0.10855 +0.079089 +3.8909e-05 +1.3582e-05 +8.3521e-06 +4.4139e-06 +0.010048 +0.008916 +0.012024 +0.0087716 +21.915 +20.664 +0.014498 +0.038736 +281.41 +0.052841 +0.116 +0.045876 +52.592 +0.014855 +0.0059324 +0.017046 +0.017892 +0.0048419 +0.0070679 +0.40907 +0.53403 +0.31196 +0.62015 +2472.8 +5024.7 +3740.6 +0.01028 +198.18 +65.313 +263.91 +0.064942 +0.20045 +0.021234 +0.028894 +0.022595 +0.030823 +0.056239 +0.57844 +0.52126 +0.0351 +0.012582 +0.007504 +0.047605 +5.4004e-06 +185.81 +0.022783 +0.019105 +0.0071829 +0.020496 +0.016122 +0.017801 +0.019332 +0.016302 +0.043327 +0.14546 +0.075413 +0.027106 +1.9848e-06 +1.1036e-05 +4.7296e-06 +0.010688 +0.0095277 +0.0095915 +33.536 +15.096 +45.921 +0.020004 +0.036517 +0.11012 +0.072967 +0.18371 +2.878e-06 +58.71 +0.020286 +0.0072614 +0.021257 +0.018985 +0.0051696 +0.017623 +0.015016 +0.60937 +0.37463 +0.41049 +5458.1 +10.158 +0.0083221 +18.792 +81.858 +91.937 +273.24 +0.062476 +0.16939 +0.017595 +0.029147 +0.015622 +0.051446 +0.069638 +0.034506 +0.49247 +0.07305 +0.021128 +0.021053 +0.089553 +1.0021e-05 +0.0018802 +0.018356 +0.02366 +0.0065828 +0.016185 +0.0079685 +0.031864 +0.045392 +0.084164 +0.08056 +0.17302 +0.075139 +0.019002 +4.8484e-06 +5.0683e-06 +3.8711e-06 +0.024493 +0.018015 +27.077 +31.855 +15.511 +177.54 +54.009 +0.047985 +0.049626 +0.11321 +0.1525 +0.0046547 +46.805 +0.022487 +0.012904 +0.039141 +0.026058 +0.0053318 +0.0082291 +5.8325 +0.0066122 +0.45067 +81.448 +31.549 +18 +0.01557 +27.598 +73.446 +289.89 +154.36 +0.033886 +386.26 +0.010438 +0.027178 +84.459 +0.089433 +0.075746 +0.033409 +0.5967 +0.10829 +0.025695 +0.01571 +0.19303 +1.6706e-05 +2.3357e-05 +0.0020546 +0.013589 +0.0057231 +0.0071034 +0.0063959 +0.026883 +0.053806 +0.036428 +0.13273 +173.3 +0.045341 +0.047146 +3.2577e-06 +9.6693e-06 +3.0402e-06 +9.4e-06 +7.4792e-06 +23.587 +19.799 +11.784 +91.995 +103.45 +0.051079 +0.077237 +0.069405 +3.337e-06 +0.0069284 +81.191 +87.019 +0.014275 +0.026181 +0.014463 +0.0035737 +0.0083141 +8.3283 +362.27 +161.48 +59.501 +66.852 +0.016179 +100.81 +35.772 +67.885 +224.26 +394.06 +0.033985 +0.083174 +30.817 +1.8271e-05 +8.8591e-06 +0.036918 +0.076411 +0.030249 +0.0030472 +0.24021 +0.043265 +0.031617 +0.24183 +3.5435e-05 +0.0033611 +0.0032474 +0.0098578 +0.011795 +0.0091226 +0.010223 +0.023326 +0.027937 +0.027932 +0.028064 +111.29 +0.073111 +0.059538 +0.088963 +3.6594e-05 +1.9786e-06 +1.0423e-05 +4.0005e-06 +9.8633 +35.141 +0.0073209 +69.693 +75.741 +0.0651 +0.018384 +1.0801e-05 +0.0027506 +0.018861 +152.74 +80.01 +0.016845 +51.767 +0.010956 +0.0055617 +75.829 +182.11 +259.56 +141.83 +80.538 +189.88 +0.032874 +0.033195 +25.118 +78.557 +198.31 +482.36 +0.032939 +3.9644e-05 +4.3631e-05 +3.9884e-05 +3.7352e-05 +13.391 +0.026062 +0.024654 +0.054103 +0.012829 +0.33624 +0.060247 +0.2247 +0.20841 +0.001981 +0.0032902 +0.011082 +0.028974 +0.027199 +0.037051 +0.015657 +0.014843 +0.02718 +0.024604 +92.502 +0.051393 +0.043725 +0.072229 +5.5349e-06 +6.4215e-06 +6.0211e-06 +10.56 +13.005 +24.696 +0.011622 +77.727 +90.043 +274.34 +5.1738e-06 +4.402e-06 +0.084558 +34.373 +260.12 +0.017151 +30.02 +13.539 +0.0049633 +180.24 +120.29 +356.77 +131.44 +100.02 +100.27 +151.9 +0.10094 +0.032967 +0.019395 +0.065063 +2 +0.97862 +1.4168 +3.8846e-05 +2.6615e-05 +1.5357e-05 +1.6432e-05 +2.2051e-05 +0.028496 +0.050352 +0.022677 +0.017201 +6.4423 +0.028529 +871.52 +0.23621 +0.19424 +0.0083699 +0.0073349 +0.022287 +0.020962 +0.037026 +0.026928 +0.10467 +0.018919 +0.015117 +120.04 +0.028485 +0.10561 +0.035395 +5.5006e-06 +3.7158e-06 +5.8991e-06 +15.972 +0.0074838 +18.524 +0.013569 +0.013602 +0.076878 +0.065357 +394.02 +554.14 +0.095828 +13.306 +82.093 +0.0080772 +20.073 +0.0066443 +0.0015835 +93.103 +249.37 +262.44 +78.234 +60.569 +154.39 +107.2 +0.092111 +6000 +6000 +2 +2 +100.04 +120.43 +121.41 +0.025502 +8.0324e-06 +1.3233e-05 +1.3573e-05 +6.8013e-06 +42.166 +0.011524 +0.018685 +7.5898 +6.2225 +1286.6 +801.18 +0.14317 +0.25396 +0.19942 +0.016374 +38.021 +0.039995 +0.099557 +0.089665 +0.044685 +0.010879 +71.768 +0.028456 +0.05115 +0.054392 +4.5725e-05 +9.2232e-06 +69.235 +0.014268 +0.0065559 +0.01852 +0.015898 +91.916 +0.14131 +7.376e-06 +9.0521e-06 +1.6032e-05 +519.05 +11.263 +53.404 +42.377 +34.791 +15.582 +0.0015798 +162.89 +192.05 +317.99 +73.708 +3.2582e-05 +3.2508e-05 +1.5372e-05 +6000 +4149.6 +4984.7 +2 +2 +1.7596 +534.99 +168.93 +0.018011 +208.91 +5.9353e-06 +0.015976 +0.0075456 +0.011869 +0.025825 +0.1071 +0.012954 +0.010061 +2.7963 +583.01 +0.21794 +0.262 +0.17877 +46.455 +0.010489 +13.561 +0.02776 +0.088544 +0.03838 +0.0079739 +28.335 +0.090437 +0.06516 +6.7856e-06 +0.00017106 +4.1091e-06 +51.025 +0.0053609 +0.0083895 +0.02286 +47.102 +133.71 +496.9 +64.618 +64.36 +96.972 +79.076 +216.63 +311.95 +38.415 +51.812 +10.783 +3.5018 +115.4 +5.4976e-06 +5.6484e-06 +5.4125e-05 +3.867e-05 +4.0171e-05 +2.9226e-05 +6000 +6000 +0.89211 +2 +2 +1.266 +0.64667 +418.62 +0.014794 +0.035631 +5.831e-06 +2.4296e-05 +0.0086243 +0.015372 +0.03313 +0.067456 +0.055137 +0.013256 +3.9672 +0.00092287 +0.1452 +0.14805 +0.18563 +0.27367 +0.092497 +12.731 +18.466 +34.214 +26.857 +47.027 +0.0059733 +0.058463 +0.038405 +9.2109e-06 +2.2831e-05 +2.9556e-05 +32.799 +0.010795 +0.012346 +0.011261 +0.012059 +0.042251 +0.24421 +929.72 +92.366 +0.053893 +138.1 +122.64 +621.42 +0.46128 +67.771 +8.4229 +5.361 +3.5068 +2.7726 +2.5543e-05 +2.6083e-05 +1.8224e-05 +5.6139e-05 +4542.5 +6000 +2 +1.0371 +2 +2 +14.843 +11.086 +319.12 +0.020247 +59.069 +2.1012e-05 +9.7823e-06 +0.0064417 +0.017478 +0.053315 +0.041396 +0.0011479 +0.0068185 +0.0043638 +0.0013485 +3.0873 +0.16564 +0.11651 +0.20489 +0.010233 +0.0068549 +21.593 +71.552 +30.994 +0.010199 +0.0048875 +0.0043378 +1.3187e-05 +4.6404e-06 +1.6419e-05 +6.4174e-05 +2.9613e-05 +0.0049225 +0.019535 +0.028827 +53.38 +0.020791 +498.84 +795.44 +0.021976 +0.04988 +178.26 +158.2 +712.31 +0.34344 +78.871 +0.0049239 +0.0015312 +2.8033 +0.0005436 +7.6231e-06 +1.7327e-06 +3.6808e-05 +6000 +4092.2 +2 +2 +0.93872 +2 +19.408 +10.848 +7.1272 +231.42 +8.1627e-06 +3.3605e-06 +3.1971e-06 +0.0089904 +0.0079553 +0.012775 +0.039549 +0.0011296 +0.0043573 +0.0091118 +0.00471 +0.0077163 +5.2384 +0.0063621 +0.018077 +0.20076 +0.01815 +0.014537 +0.0035083 +51.063 +28.662 +0.0060156 +0.0041244 +0.0023391 +0.006986 +3.07e-05 +7.7237e-06 +5.3307e-05 +5.8566e-05 +2.3657e-05 +0.0077484 +0.011225 +0.09302 +0.014383 +305.88 +697.33 +0.036298 +0.024342 +125.93 +412.19 +1556.3 +0.31941 +119.58 +0.0047299 +0.00090425 +3.9539 +0.00049446 +1.1462e-05 +7.608e-06 +1.1186e-05 +6000 +6000 +2 +1.3096 +0.42928 +2 +6.0208 +7.745 +13.817 +11.547 +4.7873e-06 +3.8792e-06 +2.0183e-05 +6.0446e-05 +6.7169e-06 +1.8499e-05 +8.4948e-06 +0.0012808 +0.0060674 +0.0079399 +0.0053937 +6.0922 +6.2203 +27.862 +54.121 +0.098075 +0.029944 +0.011378 +0.0025021 +0.0041784 +19.664 +19.362 +0.0055268 +0.0032824 +0.0059059 +0.0075303 +2.0485e-05 +3.0454e-05 +8.0804e-05 +3.0306e-05 +2.1426e-05 +0.027283 +0.048885 +0.063985 +375.29 +414.55 +0.075677 +67.37 +162.83 +0.23106 +1330.8 +0.02519 +0.0057621 +1.2822e-05 +0.0022411 +1.2755 +0.0006105 +10.453 +2.0933 +6.0394e-05 +6000 +5839.4 +5236.5 +1272 +0.41726 +1.6587 +19.621 +9.8083 +19.571 +23.521 +3.6713e-06 +1.9119e-05 +3.1752e-05 +5.6851e-05 +3.9968e-06 +2.9245e-06 +0.0030799 +0.0026298 +0.022798 +0.012925 +0.0061616 +8.0566 +10.098 +28.156 +0.011668 +0.070072 +0.021395 +0.012649 +0.0025579 +0.0084178 +0.0049549 +0.00085375 +0.0028304 +0.0026286 +0.010617 +0.0045605 +4.9351e-06 +1.7173e-05 +6.9811e-05 +5.2192e-06 +3.5938e-05 +0.024335 +0.031511 +0.16048 +998.27 +456.75 +991.91 +206.28 +123.71 +593.94 +0.057166 +0.089101 +0.00959 +0.077936 +0.087137 +1.0541 +2.973 +9.8521 +4.6754 +7.609 +6000 +2458.9 +2468 +1080.4 +0.77322 +0.55087 +0.58741 +6.9197 +15.548 +18.1 +46.231 +7.1506e-05 +5.6885e-06 +1.1326e-05 +1.5941e-06 +0.019796 +0.0062482 +0.0023728 +0.021373 +0.024499 +7.8985 +2.7384 +13.623 +36.068 +28.971 +0.090768 +0.054016 +0.0068777 +0.0094686 +0.0065724 +0.0046961 +0.0012289 +0.0027698 +0.0029001 +0.010836 +0.0049029 +14.294 +2.7776e-05 +8.2964e-05 +6.854e-06 +0.0099124 +0.0077718 +0.014085 +0.10048 +0.79601 +700.27 +1394.8 +420.83 +389.6 +491.64 +7.2125e-06 +0.06885 +623.92 +175.46 +0.3649 +1.3051 +3.1052 +12.954 +6.5447 +3.3335 +5839.4 +2726.5 +2585.2 +969.86 +0.35624 +0.26205 +0.29837 +1.0192e-05 +5.0717e-06 +1.1496e-05 +9.2781 +9.3613 +23.256 +5.5553e-06 +0.047138 +0.017976 +0.010076 +0.0047416 +0.041541 +8.7209 +5.8648 +3.6775 +15.88 +24.375 +31.199 +0.10438 +0.031465 +0.013876 +0.025309 +0.010164 +16.958 +2.8234 +0.0012099 +0.0086919 +0.014569 +0.0084334 +17.86 +0.00035592 +0.00014952 +2.0445e-05 +0.012668 +0.011203 +0.011911 +0.035173 +0.12892 +426.33 +513.43 +709.46 +603.71 +754.59 +0.11199 +2.8167e-06 +0.11733 +365.85 +0.30307 +1.933 +7.3606 +12.184 +6.1023 +3.0081 +10.036 +1521 +1446 +0.42782 +0.54209 +0.14735 +5.7922e-06 +2.2536e-05 +1.0497e-05 +1.6221e-05 +1.0651e-05 +2.1999e-06 +0.043308 +0.07008 +0.085604 +0.036187 +0.024395 +0.011559 +16.506 +8.8251 +2.8509 +2.9803 +13.55 +49.954 +14.044 +0.087939 +0.019378 +0.012807 +0.017934 +0.010869 +0.013575 +1.6657 +0.0020318 +0.0049264 +0.0085334 +0.016548 +19.1 +8.4262e-05 +5.9375e-05 +3.0898e-05 +4.2635e-06 +0.0072153 +0.020403 +0.013092 +0.063733 +0.023095 +706.97 +414.73 +561.81 +583.08 +0.0020261 +211.7 +262.07 +421.31 +0.0015366 +0.88418 +18.062 +0.0045805 +7.8957 +0.0010562 +5.7128 +8.9081 +780.01 +802.15 +8.1876e-06 +4.3923e-06 +2.819e-05 +1.1478e-05 +2.8511e-06 +8.4036e-06 +0.00027731 +0.01344 +0.018552 +0.011287 +0.051091 +0.052047 +0.034535 +6.3346e-06 +0.0073226 +11.444 +2.9458 +3.5658 +11.447 +0.13536 +0.19877 +0.027293 +0.02031 +0.011625 +0.013602 +0.010543 +0.015547 +0.00054723 +5.564 +9.62 +54.679 +0.0090351 +0.010949 +8.1705e-05 +3.4805e-05 +3.8671e-06 +6.2894e-06 +0.012842 +0.021559 +0.017889 +0.091523 +0.019308 +266.02 +615.17 +555.65 +255.66 +48.91 +0.13518 +166.1 +0.0032529 +0.0015394 +2.2295 +10.092 +0.002694 +14.312 +0.0016751 +6.4326 +6.7649 +352.36 +0.29161 +5.5861e-06 +2.1274e-06 +3.5199e-06 +1.2111e-05 +3.0879e-06 +6.5266e-06 +0.00075117 +0.0074467 +0.017732 +0.028132 +0.028142 +0.057749 +5.0091e-06 +1.8737e-05 +1.568e-05 +8.5588 +8.2889 +0.2517 +0.07381 +0.093311 +0.087179 +0.03202 +0.015703 +0.013477 +0.016869 +0.043501 +0.065292 +0.18598 +0.092577 +0.14861 +0.16614 +0.44119 +0.0046269 +2.0478e-05 +3.9581e-05 +1.4735e-05 +2.5938e-06 +7.892e-07 +0.016987 +0.019828 +0.078471 +0.27178 +0.13774 +971.57 +1517.3 +208.57 +58.711 +0.1475 +0.00019986 +0.0013711 +0.0016673 +10.781 +4.5664 +0.0020127 +19.575 +6.2006 +0.0039491 +15.561 +442.02 +2.4469e-06 +4.9945e-06 +4.7797e-05 +5.4648e-06 +3.2764e-06 +8.1617e-06 +1.2342e-06 +0.0010976 +0.011337 +0.046865 +0.044229 +0.027133 +0.12677 +2.819e-06 +5.3603e-06 +5.4862e-06 +12.911 +0.035007 +0.1881 +0.15001 +0.095093 +0.051564 +0.047951 +0.1144 +0.1023 +0.05922 +0.03292 +0.094742 +0.097381 +0.14476 +0.26779 +0.42137 +0.14448 +1.1079 +3.0241e-06 +6.9073e-06 +3.6347e-06 +3.097e-06 +5.8345e-06 +6.6494e-06 +0.017542 +0.30261 +346.86 +654.89 +880.85 +654.55 +249.66 +45.907 +211.96 +0.00032145 +0.00092865 +0.0011159 +5.3687 +0.0017044 +0.0023973 +25.589 +10.345 +0.0088593 +11.903 +2.1368e-05 +3.2631e-06 +5.0632e-06 +0.000104 +0.00011297 +5.9103e-06 +7.7958e-06 +1.1299e-05 +0.0023192 +0.0035882 +0.043807 +0.022529 +0.041125 +0.079182 +3.9732e-06 +6.9966e-06 +7.1924e-06 +0.024733 +0.063464 +0.21558 +0.08722 +0.086118 +0.011231 +29.685 +129.33 +532.58 +465.92 +208.45 +564.91 +0.15818 +0.091039 +0.20784 +850.86 +0.35057 +0.055337 +6.8438e-06 +4.74e-06 +8.1545e-06 +7.7128e-06 +1.4198e-05 +9.065e-06 +1.5977e-05 +851.21 +424.45 +433.74 +1911.8 +1300.2 +335.69 +0.0015122 +3.4667 +0.00024852 +0.0020439 +0.0021996 +0.0028635 +0.0027434 +0.002446 +41.455 +18.885 +25.53 +42.964 +5.8604e-06 +2.2878e-06 +1.9812e-06 +1.9787e-05 +4.8935e-05 +3.0584e-06 +2.2982e-06 +5.0755e-06 +0.0021166 +0.0040382 +0.015958 +0.019545 +0.053941 +0.019307 +0.0032902 +0.0018827 +0.007382 +0.025764 +0.033634 +0.20659 +0.0058382 +0.0027374 +0.0091346 +0.017889 +221.45 +249.89 +0.21625 +70.395 +617.52 +0.076253 +0.1245 +0.054475 +0.064757 +0.028573 +0.042348 +1.3564e-05 +1.5352e-05 +2.3669e-05 +2.1923e-05 +4.0201e-06 +5.2e-06 +1.5072e-05 +15.373 +306.34 +603.09 +1057.6 +1921.5 +304.07 +0.0014065 +0.0010346 +0.00031605 +0.0015167 +0.0013149 +0.0025728 +0.0022907 +0.0035685 +44.381 +0.0023242 +0.66494 +9.0554e-06 +1.1954e-06 +2.3624e-06 +7.1026e-06 +4.9531e-06 +4.5962e-06 +1.1707e-05 +4.4904e-06 +3.453e-07 +0.0022756 +0.007747 +0.020408 +0.012737 +0.040103 +0.02912 +4.518e-05 +0.0013075 +0.015126 +0.0097186 +0.0047583 +0.012412 +0.0075046 +0.0041142 +0.009146 +0.018245 +293.09 +201.65 +0.068745 +134.09 +215.21 +155.37 +0.093871 +0.063623 +0.10179 +0.051514 +8.6557 +2.1398e-05 +2.4414e-05 +1.7823e-05 +5.5816e-05 +8.5047e-06 +3.1459e-05 +9.849e-06 +7.9809e-06 +16.366 +1073.3 +0.25156 +0.19081 +402.82 +0.00085413 +0.0005534 +0.00044049 +0.0011797 +0.0017816 +0.0020836 +0.0049496 +0.0043551 +0.010172 +10.549 +0.0020077 +1.6516e-05 +1.7769e-06 +8.0451e-06 +9.4329e-06 +3.0378e-06 +6.3156e-06 +1.3578e-06 +2.2231e-06 +1.3782e-06 +1.5439e-06 +0.012772 +0.017731 +0.015885 +0.054111 +0.066776 +0.0021918 +0.011712 +0.0094865 +0.0093768 +0.002875 +0.0094018 +0.018767 +0.011114 +0.02677 +0.036441 +353.63 +0.1002 +0.035612 +0.098239 +0.022403 +0.098379 +46.251 +55.825 +86.094 +26.556 +14.846 +1.7155e-05 +2.1736e-06 +2.9292e-05 +1.2531e-05 +4.2716e-05 +9.1892e-05 +2.0216e-05 +3.8024e-05 +5.2909e-05 +0.041089 +0.18415 +591.7 +0.0027504 +0.0014306 +0.0004465 +0.0011739 +0.0023305 +0.0023479 +5.2192 +0.013909 +20.599 +24.836 +0.0020509 +2 +2.774e-06 +1.3818e-06 +7.1988e-06 +3.9631e-06 +5.4121e-06 +5.9862e-06 +2.0456e-06 +2.1124e-06 +5.9129e-06 +9.583e-06 +0.0099545 +0.020683 +0.012191 +0.0060056 +0.0020178 +0.0063626 +0.0081151 +0.0077169 +0.0063101 +0.003057 +0.0069759 +0.0092996 +0.013447 +0.019173 +0.017007 +0.0085207 +0.096741 +0.0010064 +0.046578 +0.085699 +162.94 +38.577 +31.32 +152.73 +42.696 +9.052 +1.8056e-06 +6.9506e-06 +2.1218e-05 +2.5674e-05 +2.9171e-05 +4.1781e-06 +8.2685e-06 +1.2274e-05 +2.8577e-05 +0.051454 +394.52 +340.32 +108.65 +0.0036529 +0.00057158 +0.0013332 +0.0022623 +0.0042637 +8.3173 +0.0269 +0.0060291 +41.883 +2 +0.0013809 +9.5444e-06 +2.2126e-06 +2.8104e-06 +7.7474e-06 +1.055e-05 +1.0579e-05 +5.5851e-06 +1.5427e-06 +3.8735e-06 +3.1868e-05 +3.1549e-05 +0.032385 +0.001654 +0.006347 +0.003331 +0.0075162 +0.0030931 +0.0049124 +0.010416 +0.0028062 +0.0064962 +0.012233 +548.21 +0.011114 +0.012546 +0.01753 +0.030613 +0.062204 +0.03321 +0.075665 +99.688 +29.877 +29.342 +185.15 +71.372 +7.5459e-06 +9.817e-06 +3.6888e-06 +5.0964e-06 +7.9193e-06 +1.3119e-05 +1.3243e-05 +1.4494e-05 +3.1957e-06 +1.7187e-05 +176.86 +362.46 +189.34 +196.62 +0.0028047 +0.0001964 +0.00088037 +0.00099004 +0.0054197 +0.010886 +0.029279 +0.012763 +0.0080943 +2 +0.0023485 +2.9382e-05 +2.9789e-05 +1.9878e-05 +3.3961e-05 +6.8099e-06 +7.9467e-06 +7.288e-07 +3.7506e-06 +2.8082e-05 +2.4958e-05 +5.342e-05 +0.013892 +0.004391 +0.0080864 +0.0075525 +0.0033456 +0.0043745 +0.0035243 +0.0068509 +72.891 +0.011128 +0.066575 +0.11731 +0.029392 +0.0063573 +0.011711 +0.0065458 +0.043787 +0.24015 +0.032246 +74.637 +2.2628e-05 +3.1325e-05 +2.9867e-06 +5.5075e-06 +3.3352e-05 +1.0808e-05 +9.7961e-06 +5.0965e-06 +9.7559e-06 +2.6001e-05 +1.0609e-05 +2.2272e-05 +1.9604e-05 +4.478e-05 +4.884e-06 +806.56 +155.19 +584.12 +0.29984 +0.30505 +0.0019024 +0.0012228 +0.0036285 +0.011183 +0.093351 +0.03849 +0.00095006 +0.00069376 +0.0032749 +1.4588e-05 +6.3414e-05 +2.3036e-05 +1.9989e-05 +9.6949e-06 +1.3617e-05 +1.7872e-05 +2.2419e-05 +4.9506e-05 +1.051e-05 +2.3654e-05 +0.0084426 +0.0069478 +0.0044515 +0.0066773 +0.0022462 +0.0024596 +0.0025031 +0.0051575 +26.002 +0.0089458 +82.43 +0.17482 +0.034716 +0.0086336 +0.016091 +0.034079 +0.090596 +0.091858 +0.089508 +0.064269 +6.1904e-05 +2.6566e-05 +2.2074e-06 +9.777e-07 +3.8808e-06 +4.6555e-06 +4.9495e-06 +7.2805e-06 +3.9843e-06 +0.041294 +0.052609 +0.012776 +0.068157 +0.10189 +662.15 +966.91 +138.22 +413.12 +0.27223 +0.11386 +0.064642 +0.0008875 +0.0019774 +0.016 +0.12864 +0.0791 +0.05336 +0.00065705 +9.3492e-06 +2.2165e-05 +1.5121e-05 +1.0654e-05 +3.1967e-06 +9.6837e-06 +1.8621e-05 +3.3583e-05 +5.8797e-05 +6.1404e-05 +0.095181 +0.075049 +0.010487 +14.433 +0.0032955 +16.189 +0.0046786 +0.0015958 +0.0044103 +0.48356 +0.00032856 +32.852 +0.05573 +0.043974 +0.034632 +0.011983 +0.073011 +0.042269 +10.293 +0.054707 +0.096138 +0.15934 +0.065775 +0.058154 +8.6168e-06 +1.6832e-06 +1.4373e-05 +3.6174e-06 +1.2091e-05 +0.071886 +111.41 +0.052368 +0.045424 +0.039561 +40.868 +22.273 +59.956 +800.1 +101.76 +296.28 +0.15203 +0.13798 +0.069936 +0.013748 +0.0065923 +0.012129 +0.1393 +0.053065 +0.047579 +0.026341 +0.0048472 +1.4855e-05 +7.0753e-06 +1.673e-05 +4.6154e-05 +4.6442e-05 +6.0423e-05 +7.0573e-05 +6.2273e-05 +5.9138e-05 +0.21108 +0.064445 +0.0096967 +0.0024153 +0.0046223 +24.194 +0.01005 +0.0022023 +0.0098255 +0.00027744 +0.00033778 +0.00014647 +0.040765 +143.39 +0.010945 +0.007238 +1.8237e-05 +0.070403 +10.48 +13.648 +21.027 +0.15576 +0.15275 +0.094592 +0.035364 +9.963e-07 +7.8112e-06 +1.5346e-06 +0.15431 +0.081447 +0.020555 +0.073418 +0.058654 +2.2841e-05 +58.627 +7.5757 +1292.6 +894.76 +114.38 +273.37 +367.09 +553.6 +0.080402 +0.025627 +0.011424 +0.0449 +0.079084 +0.037147 +0.035803 +0.007274 +0.011162 +0.011486 +9.2551e-06 +3.3198e-05 +2.4754e-05 +0.0002024 +2.5662e-05 +4.5082e-05 +7.3556e-05 +1091 +0.13323 +0.073646 +0.0038128 +0.0014932 +0.0075837 +43.609 +0.00495 +0.0030549 +0.01066 +0.00041381 +0.00038719 +1.3212 +16.713 +0.014015 +0.011351 +0.011097 +82.576 +0.0053031 +0.0027742 +0.0028972 +0.079103 +0.14552 +0.080303 +0.085 +0.018782 +0.010759 +2.7439e-06 +0.040667 +0.12811 +0.070442 +0.039219 +0.04722 +3.6087e-05 +1.3702e-05 +32.646 +14.646 +747.02 +421.06 +179.62 +361.91 +211.13 +0.28065 +0.090482 +0.033944 +0.02668 +0.064484 +0.14006 +0.021352 +0.01414 +0.0064925 +0.0059615 +0.021805 +0.014368 +0.015646 +4.8526e-05 +1.0011e-05 +1.1582e-05 +7.3422e-05 +0.00012026 +0.10778 +0.28338 +0.0016095 +0.0053049 +39.745 +0.0081803 +0.0069067 +0.0023986 +0.0049768 +0.00091437 +0.00057868 +0.00057691 +0.00047154 +0.002575 +20.39 +0.0096853 +0.024267 +89.832 +0.0051551 +0.087016 +0.15611 +0.054265 +0.14311 +0.11508 +0.057367 +0.019528 +0.012062 +2.3145e-06 +0.087082 +0.11111 +0.16237 +0.068916 +3.522e-05 +2.7709e-05 +1.833e-05 +25.372 +0.94169 +589.3 +367.15 +295.54 +0.11891 +0.046323 +716.59 +0.03391 +0.059941 +0.0042318 +0.0024308 +0.16902 +0.045407 +0.024287 +0.009249 +0.0073505 +0.026017 +0.010993 +0.008711 +0.010857 +2.5691e-05 +1.0643e-05 +5.489e-05 +2.9398e-05 +0.00010334 +7.6915e-05 +0.0023035 +0.0050295 +0.01121 +0.0042311 +0.0058278 +0.0032937 +0.0056575 +0.0020429 +0.0017221 +0.00048275 +0.0003405 +0.0026037 +0.010989 +78.734 +0.030871 +138.01 +127.21 +0.075979 +0.16718 +0.033606 +0.049413 +0.071763 +0.068186 +0.028917 +0.019057 +1.8026e-05 +0.071193 +0.10832 +0.18275 +0.11711 +0.052414 +6.1159e-06 +3.1658e-06 +0.060527 +0.33475 +510.32 +0.084435 +137.1 +0.025233 +0.031651 +0.10335 +0.028916 +0.0070727 +0.013595 +0.058236 +0.3156 +0.043638 +0.024856 +0.043439 +0.0052032 +0.025251 +0.012967 +0.0064451 +0.0071064 +0.0043197 +2.9187e-06 +7.2202e-06 +3.8776e-05 +0.00024376 +0.018132 +0.0026303 +0.0042276 +38.93 +0.0032753 +0.0029461 +0.0099841 +0.0057437 +0.0028765 +0.0016319 +0.00083125 +0.00073447 +0.0023654 +2.0924e-05 +102.5 +0.042203 +266.56 +160.23 +5.2916e-06 +0.21804 +0.055426 +0.021829 +0.066352 +0.11427 +0.081744 +0.018183 +8.9715e-06 +3.2828e-06 +0.094758 +0.077061 +0.11045 +0.13725 +203.47 +3.667e-06 +0.26593 +0.48562 +0.010841 +36.91 +0.038533 +113.88 +0.028976 +0.025033 +0.0044122 +0.026079 +121.96 +0.10782 +0.31638 +82.107 +0.014351 +0.01687 +0.016171 +0.01712 +0.0083715 +0.0082244 +0.0082581 +0.0057142 +0.0084223 +5.8064e-06 +1.8525e-06 +3.9208e-05 +1.5717e-05 +0.0016971 +0.0026239 +15.653 +0.0014793 +0.011826 +0.0087222 +0.0061228 +0.0019653 +0.0030895 +4.8117 +0.0013371 +7.6717e-06 +4.2508e-06 +1.4079e-05 +110.58 +199.87 +117.23 +0.050148 +0.17177 +0.022722 +0.024115 +0.13412 +0.27001 +0.18067 +1.9326e-05 +6.2515e-05 +8.3615e-06 +6.8975e-06 +0.11319 +0.16152 +0.15457 +0.20758 +0.2324 +1.476e-05 +0.68783 +0.0090707 +93.717 +62.625 +72.696 +0.023334 +0.015102 +150.22 +116.53 +81.836 +0.12543 +1475.2 +29.695 +0.018057 +0.01984 +0.0057886 +0.025946 +78.304 +0.006735 +0.0039523 +0.0042377 +0.0068401 +0.015725 +1.787e-06 +9.3927e-06 +54.224 +0.003016 +0.0022478 +0.0030127 +0.0017203 +0.013604 +0.0033182 +0.0039505 +0.003061 +0.0043289 +8.4944 +0.0012101 +5.1425e-06 +1.1961e-05 +6.2837e-06 +121.42 +154.18 +152.15 +259.3 +0.054576 +0.02116 +0.032155 +0.13831 +8.3571e-06 +1.4291e-05 +5.4787e-06 +6.0374e-06 +7.8012e-06 +1.3783e-05 +1.8706e-05 +3.3564e-06 +471.96 +0.18138 +0.1907 +0.016569 +0.0081013 +0.0034524 +49.054 +0.011698 +0.0094782 +0.022114 +361.11 +238.2 +59.962 +98.418 +0.0084876 +0.013485 +0.030753 +0.011717 +0.0091555 +44.793 +48.29 +76.825 +160.47 +0.0040635 +0.0052465 +0.0052969 +0.0097493 +1.6214e-06 +3.6701e-06 +70.241 +0.002463 +0.0058414 +0.0040832 +0.0018311 +0.012847 +0.0033194 +0.005225 +0.0012695 +0.0016668 +9.7894 +6.7626e-06 +7.0366e-06 +4.4752e-06 +3.4006e-06 +2.7681e-06 +197.42 +227.58 +117 +0.042688 +0.051017 +0.046474 +1.3617e-05 +6.1527e-06 +8.7851e-06 +2.0834e-06 +4.5807e-06 +4.487e-05 +8.4579e-06 +1.1244e-05 +1.5476e-05 +1.5494e-05 +125.88 +85.286 +0.011932 +0.0093848 +0.0084025 +0.022319 +0.017765 +1892.3 +0.050765 +935.6 +273.42 +117.36 +203.77 +0.010011 +0.012679 +0.028341 +0.01737 +0.011368 +67.715 +39.457 +67.791 +245.31 +104.45 +111.68 +0.005765 +0.0090304 +0.0020171 +154.83 +0.024733 +0.0063356 +0.0074041 +0.0024325 +0.00082242 +0.0058143 +0.0022833 +0.0078461 +0.0018696 +0.0040656 +8.6596 +0.0093915 +1.1003e-06 +7.3427e-06 +1357.8 +3100.9 +148.43 +91.361 +307.49 +0.023763 +2.272e-07 +5.741e-07 +6.0402e-06 +1.4137e-05 +2.0482e-05 +1.0709e-05 +8.3907e-06 +8.53e-06 +1.0609e-05 +3.7686e-06 +6.7858e-06 +95.63 +82.028 +120.17 +0.015008 +0.041198 +15.432 +0.040936 +0.056516 +0.14346 +0.029926 +0.21377 +0.073481 +97.298 +290.1 +0.01028 +0.012028 +0.018099 +8.6837e-06 +3.3348e-06 +8.534e-07 +29.045 +58.197 +94.114 +286.98 +215.47 +255.29 +0.017873 +1.603e-05 +0.091003 +0.018392 +0.0098902 +0.0080227 +0.0024142 +2.0188e-06 +0.0023907 +0.0014608 +0.0028496 +0.0029781 +0.0022497 +0.0077264 +0.015932 +0.15917 +667.3 +824.26 +2269.4 +123.87 +148.01 +150.74 +1.2131e-06 +8.558e-07 +2.6392e-06 +8.5925e-06 +1.077e-05 +7.1627e-06 +9.4142e-06 +4.6302e-06 +4.8062e-06 +3.4325e-06 +2.1603e-05 +90.213 +53.176 +63.43 +128.25 +0.014606 +132.72 +292.68 +0.033597 +0.096708 +0.29855 +0.006042 +0.0054068 +211.21 +2.306e-06 +310.59 +0.017646 +0.012729 +1.9727e-06 +2.9127e-05 +6.8753e-06 +2.7058e-06 +0.24876 +31.305 +87.73 +438.9 +77.87 +51.165 +1.5116e-05 +147.86 +0.053976 +137.33 +0.010231 +0.0055297 +0.0038527 +0.0006612 +0.0015844 +0.00077647 +0.0014473 +0.001046 +0.0017294 +2682.8 +0.41224 +0.059454 +0.08024 +0.34401 +44.057 +38.011 +153.52 +180.51 +5.7692e-06 +1.2538e-06 +1.099e-06 +3.8868e-06 +4.4684e-06 +1.3979e-05 +3.0668e-06 +2.1989e-05 +1.3407e-05 +1.1574e-05 +2.496e-05 +59.86 +0.011429 +82.481 +9.9403 +0.047909 +0.04504 +294.71 +91.442 +0.008805 +0.020988 +0.0055653 +0.003125 +0.011394 +133.51 +283.97 +0.015136 +0.017495 +4.9855e-06 +1.3605e-05 +0.02268 +0.0034862 +0.073882 +0.0050615 +572.19 +299.05 +139.56 +25.512 +0.027628 +0.018144 +0.065516 +275.83 +0.010943 +0.0037833 +0.0027835 +0.00067402 +0.0015372 +0.00082221 +0.00076279 +0.13801 +0.053343 +0.01949 +0.56351 +82.379 +0.023542 +18.883 +23.609 +20.748 +7.722e-07 +1.3023e-05 +4.9211e-06 +1.0245e-06 +2.0563e-06 +2.2641e-06 +9.1124e-06 +1.5535e-05 +1.9872e-05 +2.9305e-05 +3.3786e-05 +1.0192e-05 +4.2678e-06 +2.0192e-06 +0.0023556 +0.0014152 +0.0045576 +0.030751 +0.01365 +0.062489 +0.085812 +0.0099928 +0.015183 +0.0071425 +0.0025967 +0.0056879 +141.64 +153.2 +105.62 +0.0079415 +1.7203e-05 +0.021826 +0.007595 +0.0056997 +0.049752 +0.0027933 +0.02704 +200.87 +91.155 +0.01052 +0.022822 +0.012279 +0.063757 +0.030392 +0.037463 +0.024507 +0.050221 +0.068014 +0.16232 +0.00084623 +0.00089577 +0.062967 +6.1892e-06 +0.89098 +0.015949 +0.067737 +46.189 +25.643 +13.568 +18.101 +1.0648e-05 +1.8655e-05 +2.2092e-05 +1.2167e-06 +3.0462e-06 +1.5229e-06 +2.8981e-06 +4.8712e-06 +4.3826e-05 +2.52e-05 +0.00010217 +1.8653e-06 +3.6854e-06 +0.0073349 +0.0016855 +0.0011295 +0.0026129 +0.034736 +96.728 +0.05526 +0.089092 +0.0032549 +0.0043508 +0.0073622 +0.0024926 +0.010928 +0.023814 +125.09 +0.018804 +134.99 +0.039866 +0.017041 +0.0079815 +0.0095673 +2.7222e-05 +1.8093e-05 +9.9412e-06 +218.59 +83.927 +0.010608 +0.010593 +0.011435 +0.05799 +0.014547 +0.035057 +0.032693 +0.032706 +0.040472 +0.24428 +0.002322 +1.3094e-05 +0.12723 +6.1405e-06 +284.59 +201.23 +37.567 +58.786 +10.43 +0.00047996 +0.00076113 +61.845 +2 +8.5704e-06 +2.4358e-06 +5.8225e-06 +2.6277e-06 +1.2056e-05 +1.2881e-05 +9.5422e-06 +2.0476e-05 +1.025e-05 +0.026133 +0.0028282 +0.0079353 +0.0011461 +0.0014806 +0.0046148 +0.038107 +0.13395 +0.26442 +0.2204 +5549.6 +0.0013498 +0.0049601 +0.0049291 +0.010411 +0.017035 +0.033054 +0.017927 +140.48 +74.659 +0.029403 +5.3086e-06 +1.5638e-05 +1.7896e-05 +5.7096e-06 +1.0409e-05 +116.94 +83.694 +41.427 +75.385 +0.0069998 +0.048799 +0.019342 +0.049854 +0.058357 +0.030476 +0.044169 +0.079582 +0.0028704 +0.44531 +92.918 +65.47 +179.55 +0.012607 +0.019118 +0.023811 +0.015122 +0.00042604 +5.0308 +0.00086945 +0.0046896 +6000 +5.8789e-06 +3.1753e-06 +2.9668e-06 +5.2241e-06 +6.0219e-06 +5.5602e-06 +4.2411e-06 +0.011659 +0.014178 +0.0033119 +0.004946 +0.0018537 +32.129 +0.010959 +0.045353 +0.085603 +0.19667 +0.47027 +3144.8 +0.0021285 +0.0036398 +0.0048881 +0.0057389 +0.17389 +0.054017 +0.022733 +0.063034 +0.018345 +0.022662 +3.6326e-06 +1.8053e-05 +2.6416e-05 +6.2086e-06 +0.016583 +0.054548 +109.02 +29.421 +0.023669 +0.011421 +0.079306 +0.047792 +0.044184 +0.026767 +0.024148 +141.62 +0.0022592 +3.5364e-05 +42.594 +68.697 +67.418 +217.64 +0.008294 +0.019402 +0.018935 +0.023311 +0.04894 +0.015665 +0.00086617 +0.013227 +0.027497 +0.01696 +5.0915e-06 +2.0541e-05 +1.5962e-05 +4.0473e-06 +7.5542e-06 +1.8255e-06 +0.0062153 +0.012302 +0.0046883 +0.0042171 +0.56312 +46.895 +0.0066638 +0.039824 +202.24 +0.10723 +0.35572 +5796.2 +0.0039996 +0.0028732 +0.136 +0.11068 +0.22108 +0.011059 +0.0066505 +0.0042229 +0.020082 +0.037387 +0.059505 +0.017214 +0.027986 +26.956 +41.943 +121.97 +66.163 +20.519 +0.011336 +0.0094087 +0.11113 +0.032434 +0.073192 +0.0095594 +0.02667 +0.0062053 +3.4574e-05 +2.113e-05 +63.065 +101.33 +50.024 +0.95452 +0.0062981 +0.027698 +0.034955 +0.039466 +0.063494 +32.538 +1.3416e-05 +0.010717 +0.015283 +0.033819 +0.036416 +155.83 +7.794e-06 +3.3883e-06 +2.838e-05 +1.9881e-05 +0.0069799 +0.0049651 +0.0025233 +0.0025888 +0.011423 +15.858 +0.012904 +0.042346 +0.047419 +0.14187 +0.2605 +4234 +0.68764 +0.063208 +9.2299e-06 +1.4075e-05 +0.0031368 +0.011051 +0.0051841 +0.0023413 +0.0070669 +0.05501 +0.046624 +0.011863 +78.545 +0.0077011 +73.49 +130.12 +96.941 +119.35 +0.0086997 +144.63 +0.073915 +0.014305 +0.033483 +1.0281e-05 +2.2904e-05 +1.5238e-05 +2.2898e-06 +9.7099e-06 +61.766 +169.86 +29.889 +54.972 +0.0074231 +0.048925 +0.053123 +0.039659 +0.1122 +0.052896 +5.1827e-06 +8.3037e-06 +68.974 +95.894 +0.053187 +0.043027 +0.073283 +0.00070731 +6.587e-06 +1.0876e-05 +0.0075451 +0.0058959 +0.0030712 +0.0016583 +15.14 +17.941 +46.243 +0.025182 +0.046808 +0.12763 +0.11228 +2574.7 +1.0319 +0.33007 +1.5433e-05 +2.0388e-05 +6.3893e-05 +1.8158e-05 +0.0052929 +0.0024673 +0.05454 +0.027418 +0.027855 +0.0075689 +34.899 +0.016269 +80.604 +165.34 +1.9238e-05 +1.1292e-05 +0.0060657 +130.35 +294 +0.0021284 +0.0019879 +9.9067e-06 +2.7608e-05 +1.163e-05 +3.0046e-05 +63.404 +60.774 +77.637 +13.579 +61.066 +0.015383 +0.061478 +0.093677 +0.09351 +0.097913 +4.2986e-05 +2.3606e-05 +2.249e-05 +4.0697e-05 +0.036944 +154.25 +59.293 +0.01806 +0.0021749 +0.0027008 +0.001792 +0.0057311 +0.0021804 +0.0023169 +0.0030378 +48.684 +0.01439 +0.031323 +0.037954 +0.071143 +0.17283 +0.12465 +1067.2 +1.4315 +0.43937 +4.5182e-06 +1.0496e-05 +42.535 +66.145 +0.0098791 +0.035279 +0.081381 +0.026183 +0.023361 +9.3252 +6.5815e-06 +1.6378e-05 +2.224e-05 +2.0522e-05 +2.3151e-05 +33.287 +22.505 +5.3733e-06 +0.0034637 +0.0034584 +0.0025741 +6.0038e-06 +4.7984e-05 +1.8324e-05 +1.7818e-05 +1.4935e-05 +132 +43.275 +27.03 +0.75919 +0.24202 +0.046907 +0.099425 +0.025692 +0.038632 +4.726e-05 +2.206e-05 +1.0404e-05 +2.5653e-05 +2.1994e-05 +147.31 +51.501 +0.044913 +0.017195 +0.0014905 +0.0015409 +0.0051897 +0.0018941 +0.00080037 +0.0046097 +65.739 +63.029 +136.79 +66.027 +3.2572e-06 +0.19911 +0.16307 +2336.1 +2 +1.0464 +2852 +142.9 +0.032328 +37.748 +32.748 +64.373 +0.052141 +0.015749 +0.028117 +2205.9 +2.8334e-06 +1.2307e-05 +4.9167e-06 +5.0323e-06 +6.0093e-06 +8.5251e-06 +1.0346e-05 +3.905e-06 +6.0784e-06 +0.006862 +0.0048841 +15.444 +16.694 +51.738 +0.043581 +0.056481 +71.542 +75.965 +16.752 +31.926 +63.979 +0.18926 +0.10619 +128.1 +0.027519 +0.023197 +6.6456e-05 +1.4827e-05 +2.6272e-05 +1.0371e-05 +2.377e-05 +0.016592 +47.038 +0.015446 +0.0016875 +0.0023637 +0.0077109 +0.0027485 +0.00066853 +0.0080203 +48.439 +102.89 +0.0045325 +0.0085354 +1.0149e-05 +0.06343 +0.19686 +2799 +1.0999 +0.28557 +3436.9 +120.23 +0.11282 +0.007043 +1.6392e-05 +173.03 +0.11251 +0.013597 +0.019164 +0.44974 +420.88 +1.3357e-05 +6.4486e-06 +6.5728e-06 +6.9227e-06 +2.709e-06 +7.7618e-06 +3.5601e-06 +2.6241e-06 +6.9374e-06 +15.732 +47.055 +0.0015385 +79.742 +212.31 +0.18968 +0.18766 +36.826 +14.529 +97.888 +49.083 +2.4287e-05 +4.8659e-05 +0.05366 +0.051708 +0.026923 +1.8578e-05 +1.6186e-05 +2.275e-05 +6.5137e-06 +3.6187e-05 +1.3932e-05 +107.63 +0.034027 +151.61 +24.525 +0.0082705 +0.0020117 +0.0019797 +0.015764 +0.027937 +0.014296 +13.242 +1.5828e-05 +0.092211 +0.075557 +0.092231 +4410.5 +1.3445 +0.1706 +3673.2 +1.5939 +7.3185e-06 +2.2957e-05 +0.004904 +134.26 +0.032007 +0.011687 +0.026178 +0.093864 +0.10813 +2.0777e-05 +1.2221e-05 +1.8277e-05 +1.0492e-05 +2.9754e-06 +9.3913e-06 +2.7934e-05 +8.0188e-06 +1.2469e-05 +11.285 +18.083 +0.0080551 +30.432 +0.0047278 +0.10581 +916.11 +36.35 +23.061 +58.527 +32.249 +36.834 +3.0328e-05 +6.8965e-05 +0.050164 +0.013437 +0.0053823 +9.565e-06 +1.8662e-06 +1.1248e-05 +6.3694e-06 +2.9031e-05 +126.41 +0.052567 +119.83 +48.057 +0.0045561 +0.0030058 +0.0020207 +0.018946 +0.025987 +0.015938 +0.033054 +0.012043 +0.11314 +0.053507 +0.099861 +5647.1 +1.1549 +702.86 +1.0327 +1.1622 +2 +0.010018 +41.537 +52.251 +59.27 +39.447 +0.0035636 +0.085909 +0.075513 +1.2208e-05 +6.326e-06 +1.7272e-05 +1.6701e-05 +7.4919e-06 +2.8059e-05 +9.7066e-06 +0.0078622 +0.0028389 +15.322 +10.51 +17.838 +5.7863 +0.010309 +26.43 +1303.4 +8.2997e-06 +14.397 +163.13 +54.651 +66.672 +2.0307e-05 +3.3123e-05 +0.00011954 +0.012588 +0.018731 +0.024527 +7.4553e-06 +8.0342e-06 +1.4937e-05 +6.0376e-06 +165.35 +0.034373 +165.64 +46.458 +24.486 +0.0028188 +0.0019149 +0.011479 +0.016795 +0.0055014 +0.01008 +0.0281 +0.057048 +0.024654 +0.091315 +0.090289 +2.8009e-05 +692.65 +0.8697 +1.8409 +1.9984 +1.6036 +66.756 +22.354 +27.799 +20.948 +13.759 +0.09675 +1.0053e-05 +4.7957e-06 +2.536e-05 +3.1526e-05 +4.8919e-05 +1.4268e-05 +6.1258e-05 +0.0029592 +0.017092 +17.547 +29.663 +0.0015002 +20.392 +0.027348 +0.010928 +21.778 +10.875 +2.0465e-05 +7.3255e-06 +124.95 +106.72 +99.002 +0.010841 +3.1262e-05 +2.4472e-05 +5.0086e-05 +0.028954 +0.030519 +0.039276 +4.6269e-06 +0.13645 +0.13278 +0.12375 +0.032825 +132.93 +59.456 +22.786 +9.0927 +0.0025599 +0.014179 +0.0096878 +0.0075471 +0.0046122 +0.0016209 +0.046237 +0.017134 +0.11031 +18.281 +1.8159e-05 +839.77 +0.57343 +2 +0.8483 +1.4129 +0.35105 +16.645 +0.011445 +41.303 +7.102 +1.4777e-05 +7.0849e-06 +1.263e-05 +1.6507e-05 +1.2828e-05 +1.0689e-05 +8.366e-06 +4.1969e-05 +0.0012148 +0.035006 +30.781 +0.013785 +7.672 +0.011632 +275.23 +0.047411 +26.205 +10.508 +2.4031e-06 +7.7738e-06 +125.96 +136.94 +0.037093 +0.01987 +2.0856e-05 +2.0605e-05 +3.7574e-05 +2.4119e-05 +1.2551e-05 +0.03044 +0.038006 +0.0066674 +0.0071871 +0.0080959 +0.015445 +0.01742 +36.044 +33.879 +9.0452 +0.084928 +0.08831 +0.0068032 +0.0039521 +0.0021946 +0.0016394 +0.0060955 +0.011405 +0.047419 +9.9047 +2.9128 +898.04 +0.32371 +1.1553 +0.81089 +0.67924 +0.61918 +11.737 +0.010154 +0.019304 +3.6409e-06 +2.4783e-05 +3.9837e-05 +5.0049e-06 +1.3898e-05 +7.1489e-06 +1.5832e-05 +1.2409e-05 +2.4948e-06 +2.717e-06 +135.77 +28.493 +0.012514 +0.018378 +0.021271 +137.95 +0.10837 +0.078308 +9.4877 +10.475 +331.43 +254.03 +176.13 +147.96 +106.04 +88.657 +98.97 +0.050104 +0.021875 +0.0063826 +0.023555 +0.0039531 +0.0076067 +0.010275 +2.5146e-06 +8.1144e-06 +3.3627e-06 +1.7223e-06 +54.305 +4.6527 +0.017378 +0.038962 +119 +184.18 +0.0028719 +0.0023036 +0.0046045 +0.0077145 +0.0085617 +12.679 +3.9873 +0.0029488 +0.26901 +3151.1 +1.0224 +0.64689 +0.78489 +0.57782 +0.011614 +0.025567 +4.6071e-06 +2.3661e-05 +2.3892e-05 +2.6159e-05 +3.6131e-05 +1.5283e-06 +1.8383e-05 +4.7899e-06 +3.856e-06 +3.2439e-06 +2.7664e-05 +32.938 +0.017277 +0.01684 +0.011313 +0.0024335 +0.017353 +0.0048975 +0.0048538 +694.71 +307.85 +252.25 +165.31 +93.909 +0.024976 +0.034458 +0.030728 +0.013596 +0.017799 +0.042803 +4.3837e-06 +4.1669e-05 +0.26241 +0.076269 +0.072796 +4.6257e-06 +1.4633e-05 +7.5508e-06 +54.768 +10.409 +0.0096186 +0.013153 +126.13 +440.09 +42.992 +0.00085592 +0.0050311 +0.0047216 +0.0043768 +0.02403 +0.010782 +0.0029467 +0.18138 +1188.6 +0.89947 +0.52688 +0.70047 +0.37798 +0.0078952 +73.912 +1.2059e-05 +7.5028e-06 +1.5795e-05 +1.5238e-05 +2.7144e-05 +9.8843e-06 +6.99e-06 +2.13e-05 +1.5767e-05 +3.81e-05 +6.0497e-05 +239.97 +0.010768 +0.0099013 +0.0071833 +0.0075325 +0.020653 +0.0037644 +0.0038616 +570.21 +182.97 +191.29 +0.091804 +0.0090394 +0.048177 +0.022192 +0.018756 +2.294e-05 +4.6302e-05 +6.562e-06 +3.1653e-06 +0.026783 +0.11868 +0.079553 +0.037082 +7.7734e-06 +3.083e-06 +4.3048e-06 +52.45 +16.445 +15.609 +0.0076192 +0.01883 +0.031968 +36.074 +71.404 +0.019126 +0.0038756 +0.015848 +0.013568 +0.018129 +0.040691 +0.02827 +993.43 +0.48146 +0.35859 +0.77617 +0.38812 +0.084631 +8.6949e-06 +1.0202e-05 +5.2249e-06 +2.8253e-05 +1.0332e-05 +1.8271e-05 +1.0702e-05 +1.7145e-05 +5.5987e-05 +1.5517e-05 +0.00020496 +22.14 +0.013371 +0.012626 +0.015591 +0.0094883 +0.0090031 +35.795 +0.0035375 +368.37 +681.38 +165.15 +0.0098403 +0.0085911 +0.0083981 +2.9934e-05 +1.3344e-05 +1.4333e-05 +7.7316e-06 +1.2509e-05 +6.4666e-06 +1.0513e-05 +0.027443 +0.12653 +0.098317 +5.1347e-06 +1.8314e-06 +9.1159e-06 +1.9621e-06 +9.9907e-06 +0.00010825 +0.0051357 +0.0086534 +0.010099 +0.031272 +0.053208 +0.039166 +68.638 +0.0034181 +0.012581 +0.029869 +0.0437 +0.068964 +0.035482 +1571.1 +1.1255 +0.36284 +0.97709 +0.58563 +0.17785 +1.3399e-05 +2.3454e-06 +8.7332e-06 +3.7313e-06 +1.5404e-05 +4.8491e-06 +5.2891e-06 +6.1447e-06 +2.2213e-05 +0.0043282 +0.0067874 +0.011676 +0.0072128 +16.255 +0.0063863 +0.012255 +48.662 +24.451 +0.002063 +0.003349 +0.47854 +0.18321 +1956.2 +0.016225 +0.0091154 +1.4583e-05 +1.5027e-05 +8.683e-06 +2.3238e-06 +2.0849e-06 +4.6043e-05 +0.02296 +0.037955 +0.081165 +0.16265 +3.9916e-06 +1.2936e-06 +1.3504e-05 +4.31e-06 +6.0974e-05 +4.6007e-05 +6.4702e-06 +0.0082252 +0.014308 +0.063233 +0.050152 +0.048827 +0.027064 +0.00076214 +0.0090725 +0.012528 +0.093631 +0.076332 +0.062463 +0.054946 +780.74 +0.14617 +0.94225 +1.1755 +0.30871 +0.40664 +8.2078e-06 +6.1463e-06 +3.5707e-06 +4.4105e-05 +5.3522e-06 +8.9714e-06 +3.9575e-06 +0.0055468 +0.0028521 +0.01171 +0.020369 +0.020294 +44.176 +0.015756 +114.16 +32.551 +0.0097104 +0.016315 +0.0092388 +0.44574 +0.53353 +0.65324 +0.5788 +3.3996e-05 +4.5049e-05 +4.9725e-05 +2.0038e-05 +4.2904e-05 +7.1308e-06 +0.026739 +0.016413 +0.0488 +0.070177 +8.5081e-06 +4.4189e-06 +2.6306e-06 +1.1488e-05 +2.0757e-05 +60.338 +1.0324e-05 +2.0678e-06 +2.0478e-05 +0.018435 +0.060583 +0.051996 +0.046074 +0.048589 +0.062206 +126.7 +0.015938 +994.02 +0.03529 +0.093527 +0.12799 +0.14734 +646.92 +390.16 +0.49678 +0.32526 +0.42467 +0.12524 +5.2149e-06 +3.079e-05 +0.0067434 +0.0075049 +0.032034 +0.0058434 +0.0099523 +0.0057999 +0.013792 +0.0065159 +0.015336 +0.054138 +62.816 +107.2 +33.28 +0.012927 +0.014269 +0.0093651 +0.031227 +1.0347 +3419.7 +0.96933 +0.25401 +1.9946e-05 +3.8728e-05 +0.0038135 +0.013972 +0.052738 +0.030519 +0.019473 +0.058286 +2.5537e-05 +4.5171e-05 +2.9298e-05 +1.3606e-05 +6.9507e-06 +9.6938e-06 +38.219 +6.7033e-06 +8.114e-06 +7.2745e-06 +70.393 +0.092134 +0.067136 +0.025989 +0.061315 +160.73 +97.778 +0.22108 +1111.3 +0.0064302 +0.33992 +0.19542 +0.1198 +0.12364 +231.36 +0.090798 +0.011877 +0.0060177 +0.0057668 +0.0057181 +0.016677 +0.013206 +0.012817 +0.043011 +0.0083075 +0.066471 +56.776 +28.075 +0.0033572 +0.0017382 +8.1415 +1.5643e-05 +0.0098319 +0.0058568 +0.013978 +0.014537 +0.021459 +60.877 +1.1568 +2762.9 +0.0056101 +0.0033927 +6.4032 +0.021671 +0.0084914 +45.423 +0.059112 +3.4204e-06 +4.2723e-06 +1.2519e-05 +2.6055e-05 +4.1349e-06 +6.2342e-05 +3.1893e-05 +1.7328e-06 +1.8152e-05 +26.312 +1.1709e-05 +1.2679e-05 +6.5251e-06 +128.11 +39.677 +0.065826 +0.04064 +0.060825 +71.179 +44.534 +0.06096 +0.012012 +0.005401 +0.70795 +0.68462 +0.10472 +0.12314 +155.69 +0.0017765 +0.0016125 +0.0071669 +0.0033905 +0.0038618 +0.011137 +0.0040705 +2.4985e-05 +158.41 +92.747 +0.03602 +99.305 +0.0077411 +0.0041965 +3.1075e-05 +3.1499e-05 +6.3556e-05 +0.004676 +0.0090775 +0.0071922 +0.016656 +0.02117 +0.064767 +47.572 +20.232 +0.0047 +0.0033179 +0.0054502 +0.013233 +0.021783 +3.3456e-05 +4.556e-05 +1.6832e-05 +3.9423e-06 +1.732e-06 +3.1499e-06 +1.4294e-05 +3.0992e-05 +8.2471e-06 +6.1064e-06 +8.6414e-06 +48.333 +2.4199e-05 +0.0094825 +0.00075736 +48.142 +14.053 +18.82 +0.024893 +0.025564 +43.529 +50.154 +0.14315 +0.0096352 +56.465 +0.015182 +0.70098 +0.095521 +0.0023798 +0.00058709 +0.0015955 +0.006727 +0.0061509 +0.017323 +0.34671 +0.33581 +0.034026 +1.087e-05 +52.681 +104.19 +0.040932 +54.515 +2.0412e-06 +4.3702e-05 +2.3997e-05 +1.9749e-05 +0.10876 +0.073929 +0.025893 +0.011474 +0.017514 +0.0024965 +0.059007 +57.359 +0.016037 +35.77 +0.005637 +0.0048726 +0.26949 +1.7876e-05 +2.9649e-05 +2.7615e-05 +1.1798e-05 +4.1392e-06 +2.9639e-06 +5.9356e-06 +4.3379e-05 +2.951e-05 +6.078e-06 +7.3678e-06 +9.094e-06 +33.041 +3.2875e-06 +0.0072236 +3.7497 +35.82 +12.906 +0.12124 +0.019709 +0.0091781 +19.982 +0.016516 +0.057138 +0.018941 +0.0087048 +1.2131 +0.89302 +0.054484 +0.001645 +0.00076139 +0.0010072 +0.038599 +0.041453 +0.033122 +0.27223 +0.37304 +0.07262 +6.6391e-06 +88.043 +95.822 +0.028656 +0.019893 +2.1952e-05 +3.0589e-05 +2.2702e-05 +3.5649e-05 +0.11282 +0.12701 +0.079565 +0.062167 +0.024536 +16.657 +0.0045343 +72.861 +0.010226 +0.013557 +28.551 +331.71 +0.32435 +0.24437 +1.2618e-05 +3.9646e-06 +9.2272e-06 +1.9015e-06 +4.9392e-06 +1.3788e-05 +2.9458e-05 +3.8693e-05 +1.1744e-05 +1.4648e-05 +1.0673e-05 +9.09e-06 +1.4405e-05 +5.2876e-06 +5.0944 +0.0029422 +0.0019697 +0.026675 +0.025186 +0.013532 +0.0039384 +0.02359 +117.31 +0.013008 +4.5109 +0.0017366 +0.54064 +0.066488 +270.1 +0.00030586 +0.00062398 +0.0037197 +0.045416 +0.038648 +0.37802 +0.31913 +6.4868e-06 +1.2711e-05 +94.32 +146.95 +0.075437 +0.049865 +3.6711e-06 +1.6258e-05 +1.7232e-05 +1.8831e-05 +668.93 +0.14128 +0.14105 +0.032431 +69.441 +10.258 +0.0013419 +0.00091415 +0.0012813 +58.737 +32.136 +39.977 +524.65 +0.090683 +1.9532e-05 +2.3695e-05 +3.14e-05 +1.709e-05 +1.4633e-05 +2.0825e-05 +1.5526e-05 +2.9746e-05 +3.2529e-05 +7.2272e-06 +8.9327e-06 +0.026009 +6.3145e-06 +0.0093052 +2.8966 +0.0025427 +0.0017852 +0.022139 +0.019489 +0.017249 +0.0030199 +74.805 +0.037956 +0.076334 +0.01862 +0.0026149 +0.30262 +0.069278 +216.96 +94.553 +0.00030772 +0.0021304 +0.039317 +0.024661 +0.42719 +6.0919e-06 +4.6626e-06 +2.9377e-06 +196.3 +100.07 +0.13384 +0.10984 +1.1303e-05 +9.0226e-05 +0.00013894 +0.33662 +723.4 +316.33 +0.10003 +0.027756 +45.96 +10.389 +0.0030943 +0.001462 +0.0013599 +0.0036955 +21.182 +26.619 +14.319 +0.090749 +0.16194 +6.9392e-06 +5.3491e-06 +2.081e-05 +8.2038e-06 +3.1546e-05 +1.6644e-05 +1.8894e-05 +9.7556e-05 +1.3254e-05 +4.3768e-06 +0.073347 +0.054799 +0.016123 +15.086 +0.00093552 +0.0053824 +0.015403 +0.0075496 +0.010225 +0.0055905 +0.043364 +0.093358 +0.085292 +0.0032672 +0.085294 +0.042181 +0.068535 +180.75 +94.454 +32.985 +0.002605 +0.00032997 +0.035736 +5.3596e-06 +5.3042e-06 +5.6365e-06 +7.1051e-06 +5.9369e-06 +87.142 +324.42 +0.11355 +3.802e-05 +0.020372 +0.029787 +644.61 +348.2 +591.87 +0.069874 +12.712 +15.811 +0.0018381 +0.0015619 +0.0012724 +0.0011885 +0.0025529 +0.0041156 +0.011199 +13.646 +0.13869 +0.11876 +8.5396e-06 +2.2767e-05 +7.9375e-06 +4.1602e-05 +4.5795e-05 +1.3486e-05 +2.3069e-05 +1.7412e-05 +7.3808e-06 +3.9912e-06 +0.095134 +0.018092 +0.0042837 +0.004492 +0.0013294 +0.0044696 +0.0074187 +0.0030373 +0.0092036 +0.0028542 +0.048642 +0.044717 +0.17464 +0.36107 +0.11972 +0.024498 +0.048004 +394.79 +131.56 +44.504 +38.375 +0.72079 +0.0004301 +0.00073373 +0.00051145 +1.194e-05 +2.3882e-05 +5.4546e-06 +156.21 +0.10991 +0.37554 +0.23606 +0.15449 +0.033444 +0.29402 +708.05 +514.7 +26.552 +29.52 +0.0069571 +0.0027698 +0.0021688 +0.0016703 +0.00113 +0.0013157 +0.006059 +12.438 +0.005917 +0.25444 +0.084238 +0.10499 +3.1323e-05 +5.5603e-05 +1.0551e-05 +2.9991e-05 +2.4167e-06 +1.6651e-06 +5.2495e-06 +9.4912e-06 +1.8037e-05 +0.019182 +0.015857 +0.012234 +0.0066923 +0.0021741 +0.0068479 +0.011296 +0.087682 +0.058208 +0.098202 +0.05385 +0.52037 +0.29594 +0.39142 +0.050139 +0.029379 +0.087055 +666.7 +0.06194 +0.11478 +0.032787 +0.025882 +0.00047098 +0.54314 +2.4859 +0.00033241 +1.5997e-05 +3.3156e-05 +2.0342e-05 +0.14629 +0.49445 +0.5239 +0.12755 +0.021471 +0.16388 +0.50507 +484.27 +25.238 +28.367 +0.0044072 +0.0015984 +0.0036715 +0.0027435 +0.00065032 +0.0010267 +0.0091466 +0.0059405 +0.096865 +0.22169 +0.083226 +0.10545 +0.065158 +1.9969e-05 +1.8527e-05 +5.4305e-06 +1.0823e-05 +3.7332e-06 +2.7316e-06 +8.2641e-06 +1.3353e-05 +0.029028 +0.041781 +0.0091493 +27.908 +0.0023152 +0.0073085 +0.11715 +174.94 +0.055453 +0.59634 +0.42005 +0.25153 +0.6321 +0.44492 +0.10475 +138.19 +0.19662 +0.068361 +0.055577 +0.10284 +0.028078 +0.024474 +0.051085 +0.97618 +1.2974 +2.3623 +0.00056469 +56.051 +0.06788 +0.13663 +0.33883 +0.24377 +0.12171 +0.11384 +0.19475 +1661.5 +33.358 +23.436 +19.538 +0.0036123 +0.0014116 +0.001335 +0.001148 +0.00046086 +0.0012245 +0.0024563 +0.14345 +0.040744 +0.07622 +0.046999 +0.061619 +0.04886 +1.7245e-05 +1.3277e-05 +6.8116e-06 +5.3689e-05 +8.0141e-06 +2.1701e-05 +6.4639e-06 +4.3209e-05 +0.02055 +0.029256 +0.014174 +43.394 +0.0052802 +0.014763 +0.22862 +337.16 +0.11036 +0.16044 +0.50231 +0.26177 +0.34095 +0.77417 +0.081884 +397.02 +0.31328 +0.073103 +0.039411 +0.061952 +0.055256 +0.045554 +0.063172 +3.9564e-05 +2.6183e-05 +4.8154 +5.7365 +35.133 +60.048 +0.094309 +0.47209 +0.19364 +0.1225 +0.063351 +3.4282 +5.4778 +0.0099629 +8.4436 +14.089 +0.0028572 +0.00089142 +0.0015233 +0.00053705 +0.00031412 +0.00068421 +3.7312e-06 +0.40698 +0.06972 +138.25 +0.034769 +0.063937 +0.030468 +1.0546e-05 +2.7055e-05 +1.1715e-05 +0.0052078 +4.1982e-06 +2.702e-05 +5.9777e-06 +1.3009e-05 +0.040822 +0.055012 +0.029614 +86.82 +0.011523 +0.017951 +263.01 +230.14 +0.22022 +0.20104 +0.50828 +0.3432 +0.2299 +0.2044 +0.057366 +0.033586 +0.10159 +0.044493 +0.044293 +0.051913 +0.020092 +0.023486 +0.11664 +1.0979e-05 +0.013456 +0.011802 +10.04 +3.1369 +0.0016116 +27.932 +63.484 +272.45 +0.1614 +0.054283 +5.6607 +5.6308 +18.573 +7.6786 +0.0033321 +0.0032171 +0.00073741 +0.00049261 +0.00037732 +0.00077995 +1.5224e-05 +4.9007e-06 +2.1298e-05 +223.09 +0.071626 +0.023454 +0.028105 +0.032082 +7.9058e-06 +4.9581e-06 +5.6477e-06 +5.8339e-06 +0.012173 +0.0088976 +0.014279 +8.4129e-06 +0.035896 +0.071444 +142.12 +148.62 +33.582 +0.021481 +444.75 +482.47 +0.15605 +0.099676 +0.54666 +0.74663 +0.086015 +0.003431 +0.0076165 +0.037609 +0.094098 +0.06481 +0.025902 +0.034305 +0.023733 +0.042958 +0.12842 +3.5656e-05 +0.020306 +0.0092914 +0.003874 +0.19528 +17.25 +0.0016034 +0.0015171 +43.47 +43.98 +115.99 +4.0655 +7.6013 +14.923 +2.801 +0.0032106 +0.0021814 +0.0010057 +0.00083833 +0.00034628 +3.1986e-05 +4.4443e-05 +3.1781e-06 +2.4833e-05 +144.96 +0.070132 +0.035428 +0.019243 +0.02097 +0.023715 +3.6185e-06 +1.0056e-05 +7.1706e-06 +0.026671 +0.008415 +0.0090284 +0.032555 +0.073094 +0.06631 +0.056157 +117.54 +27.132 +1.5546e-06 +0.32611 +497.18 +0.1785 +0.1281 +0.49265 +0.7388 +0.018966 +0.0047789 +0.01116 +0.038584 +248.06 +0.073314 +0.077004 +0.13896 +0.072064 +0.094237 +9.4865e-06 +3.4804e-05 +0.036138 +0.0044217 +0.0052052 +0.0055382 +0.0055762 +40.511 +0.0011165 +0.0046845 +46.554 +25.386 +4.2317 +0.0027621 +9.2628 +9.7267 +7.0141 +0.00065055 +0.00055295 +3.2178e-06 +6.7851e-06 +9.2011e-05 +1.0991e-05 +3.5937e-05 +3.6764e-05 +0.025372 +0.020432 +0.026134 +0.013296 +0.012103 +0.016439 +6.3615e-06 +3.0102e-05 +3.9288e-06 +6.0661e-06 +0.028773 +0.013021 +0.031586 +0.10125 +0.040659 +290.14 +139.88 +20.315 +124.68 +750.1 +0.19521 +0.15144 +0.1331 +0.61879 +0.003746 +0.01228 +0.0065286 +0.0064479 +0.057295 +0.052535 +0.058739 +0.097417 +0.38238 +0.045861 +0.0083664 +1.3177e-05 +0.007158 +0.027096 +0.0048323 +0.0097772 +0.0060059 +0.0043288 +0.017048 +0.068802 +0.016621 +0.02344 +30.982 +0.0029945 +0.01152 +16.257 +6.3172 +3.463 +2.0917 +5.4221e-06 +3.6881e-06 +2.0741e-05 +1.2757e-05 +8.2005e-06 +2.0037e-05 +1.9051e-05 +0.026527 +0.034757 +0.047871 +0.014593 +0.010695 +0.012597 +0.018021 +3.7074e-05 +3.512e-05 +1.1881e-05 +0.078251 +0.011894 +0.019029 +0.22463 +0.14463 +393.03 +192.94 +117.83 +142.09 +619.7 +927.86 +0.084806 +0.1078 +0.30443 +0.0039578 +0.008987 +0.010337 +0.011357 +0.078241 +286.09 +0.014316 +0.071119 +0.010285 +0.0089746 +0.0094361 +2.0802e-06 +0.0083937 +0.010924 +21.351 +0.0089005 +0.0068735 +25.756 +0.0093225 +0.03385 +0.021985 +0.011901 +0.015115 +0.0049582 +0.012823 +0.02355 +4.1032 +1.1748 +0.00034719 +3.6448e-06 +1.6638e-06 +1.0974e-05 +2.5776e-06 +1.7872e-05 +5.1307e-06 +122.75 +64.422 +0.017031 +0.01718 +0.017889 +0.0099285 +0.01217 +0.000325 +4.6682e-05 +2.7197e-05 +3.8411e-06 +1.1383e-05 +0.022085 +0.012853 +1037 +0.23697 +40.013 +271.25 +260.47 +378.07 +987.66 +451.4 +0.11658 +0.25891 +0.43279 +0.0046512 +0.013075 +0.017484 +0.012776 +0.07833 +0.028767 +0.023585 +0.057519 +0.006165 +0.010444 +0.0092054 +0.0078274 +19.529 +6.1049 +0.010339 +0.0081509 +0.0050337 +13.506 +75.304 +42.628 +0.096098 +48.419 +48.47 +0.0097999 +0.018549 +0.017666 +6.0044 +1.8886 +0.052524 +0.0068706 +2.2691e-05 +6.6399e-06 +5.7007e-06 +0.0046673 +34.836 +160.39 +132.86 +0.039268 +0.017941 +0.015285 +0.0065772 +9.5101e-06 +2.5768e-05 +3.3214e-06 +1.7778e-05 +1.4181e-06 +6.0031e-06 +1.6431e-05 +0.0020129 +0.3236 +18.508 +102.96 +289.71 +250.24 +213.9 +941.07 +646.34 +0.16845 +670.7 +0.019079 +0.0021417 +0.0097067 +0.014573 +0.029762 +0.012856 +0.01683 +0.022418 +0.0070085 +0.12013 +0.030288 +72.09 +32.42 +18.547 +9.6748 +0.0085159 +0.0039965 +116.46 +0.031955 +124.02 +0.022491 +230.45 +73.73 +199.69 +0.0062988 +0.014835 +37.759 +46.237 +0.023324 +0.044769 +0.0079678 +0.0058148 +1.2035e-05 +0.015303 +0.0070147 +41.684 +101.63 +0.033917 +0.020698 +0.0095374 +0.011932 +6.1426e-06 +8.4487e-06 +0.00011804 +2.9996e-05 +1.9248e-06 +2.6253e-06 +2.7998e-06 +18.859 +0.0024047 +6.5178 +19.314 +62.283 +56.91 +169.01 +364.45 +988.3 +497.38 +0.28241 +0.0086644 +0.01452 +0.0027612 +0.007064 +0.010662 +0.0028807 +0.0043086 +0.0056782 +0.31627 +0.13761 +0.13861 +35.59 +75.168 +46.87 +0.017666 +0.054403 +47.963 +0.014633 +269.68 +59.672 +134.25 +0.035327 +0.062732 +0.034191 +0.0063292 +0.0068802 +0.015375 +45.986 +55.791 +0.015371 +0.052492 +0.041646 +0.025945 +2.7143e-06 +0.039346 +0.0096603 +0.0059025 +44.398 +0.023623 +0.023455 +0.016565 +4.1817e-05 +1.0333e-05 +1.1642e-05 +6.9868e-06 +1.3281e-05 +1.0185e-05 +6.0185e-06 +0.0045732 +18.023 +0.0021233 +10.976 +14.498 +39.186 +56.899 +253.57 +234 +572.48 +0.020862 +0.016775 +0.0090478 +0.006041 +0.089706 +0.026336 +0.0056516 +0.003965 +0.070576 +0.19669 +0.13979 +0.13156 +0.11158 +0.062337 +69.783 +0.014636 +0.038561 +0.019786 +0.01599 +0.0090327 +196.14 +83.745 +132.07 +45.162 +0.032471 +0.018891 +39.593 +0.013871 +0.0076791 +0.017992 +0.0060628 +0.0027495 +0.0040028 +0.010576 +0.0026723 +0.073887 +0.041474 +0.0056036 +0.011441 +37.035 +0.019409 +0.0091101 +0.01843 +2.5979e-05 +1.9588e-06 +9.9334e-06 +2.1981e-05 +9.9103e-06 +2.4215e-06 +8.8715e-06 +0.0066723 +0.01032 +0.0017681 +12.705 +20.939 +57.243 +86.402 +297.02 +313.06 +0.0048275 +0.0012072 +0.02883 +0.0050763 +0.081042 +0.003141 +0.0080397 +0.0028469 +0.0092216 +0.046696 +0.20192 +0.099798 +0.10888 +0.081279 +125.15 +54.232 +0.0056066 +0.015904 +0.022237 +52.883 +0.01055 +334.54 +103.45 +99.209 +32.083 +0.029776 +56.025 +103.14 +0.034313 +0.0058288 +0.024661 +0.010477 +0.0040482 +0.0025593 +0.0060988 +0.0028976 +0.031712 +0.090053 +0.011085 +0.016511 +88.656 +0.016001 +0.010918 +0.021256 +2.2673e-05 +4.7076e-06 +5.6549e-06 +2.7241e-05 +1.4521e-05 +3.9006e-06 +0.0034946 +0.011914 +0.0068839 +0.0020158 +7.9575 +32.761 +25.254 +54.286 +0.010723 +0.0026654 +0.0041926 +0.0012439 +0.0020542 +6.2664e-05 +0.0091266 +0.0060013 +0.0048837 +0.0026944 +0.008527 +0.0844 +0.26783 +0.15741 +371.31 +0.033401 +138.35 +70.642 +34.033 +0.0091406 +0.01914 +0.011561 +0.012597 +358.13 +222.11 +85.912 +27.331 +0.054214 +69.679 +161.87 +33.624 +0.012087 +0.021224 +0.0085426 +0.0091637 +0.0032967 +0.0099588 +0.0012455 +0.0010973 +0.04074 +0.017517 +0.028611 +93.679 +0.035507 +0.015002 +0.023814 +3.4484e-06 +1.3058e-06 +1.92e-06 +1.0105e-05 +0.006843 +0.0053583 +0.0072121 +0.006819 +0.0055213 +0.0030108 +10.868 +51.48 +47.223 +0.30758 +0.096419 +0.0027825 +0.0068663 +0.0012995 +0.0010282 +0.0012274 +0.017228 +0.0036891 +0.0087619 +0.0026678 +0.063714 +0.15106 +0.31773 +0.16443 +421.86 +0.051734 +152.39 +120.18 +60.206 +0.018053 +22.018 +0.019307 +0.017373 +375.26 +238.84 +172.97 +0.051523 +77.951 +103.32 +144.54 +47.974 +0.0074569 +0.01246 +0.0074994 +0.010675 +0.0022687 +0.017646 +0.0012388 +0.050216 +0.034964 +0.29765 +0.033175 +0.033369 +0.032873 +0.018237 +0.019119 +0.074318 +0.075527 +3.503e-06 +1.0898e-05 +0.0029441 +0.0035312 +0.0035826 +0.0111 +0.0070684 +0.0072816 +16.693 +17.589 +30.502 +0.24716 +0.086018 +0.07669 +0.088326 +0.00256 +0.00051439 +2.6213 +0.0015627 +0.0033325 +0.02119 +0.0060396 +0.010169 +0.13325 +0.306 +0.46097 +587.13 +0.021212 +0.053062 +137.92 +56.683 +0.010774 +0.016826 +42.272 +48.647 +188.31 +217.52 +0.13035 +0.04184 +108.33 +0.055323 +143.39 +77.212 +6.8583e-06 +0.0062281 +0.007497 +0.0038838 +0.0024013 +0.0056757 +0.0013842 +0.087742 +0.063351 +0.15816 +4.7724e-06 +0.026864 +0.045873 +0.016988 +0.0080418 +0.067729 +0.069539 +0.025596 +0.0037205 +0.0016765 +0.0049366 +0.0063452 +0.0057471 +0.012372 +0.017014 +19.952 +19.778 +0.54301 +0.29613 +0.17005 +0.11726 +0.09289 +0.15757 +2.1461e-05 +2.9168 +0.0024895 +0.042978 +0.023485 +0.0061835 +0.024954 +0.074019 +0.30684 +0.58287 +456 +0.1229 +147.36 +188.21 +0.0075631 +42.37 +0.028598 +39.962 +53.527 +95.719 +92.598 +0.12943 +0.046118 +134.23 +158.81 +0.065458 +1.4096e-05 +1.5739e-05 +0.0042862 +0.0043728 +0.0062933 +0.0014411 +0.0045803 +0.00084943 +0.043544 +0.081918 +7.2792e-06 +3.8644e-06 +1.2103e-06 +1.9201e-05 +0.011895 +0.010525 +0.094504 +0.035743 +0.024133 +0.087452 +0.0010599 +0.0044553 +0.0095873 +0.0095984 +0.0092944 +0.013129 +14.146 +0.35204 +0.32127 +0.42485 +0.25826 +0.20925 +0.16786 +0.0053135 +6.9471e-06 +2.2946 +0.0053938 +0.02067 +0.011002 +0.0074563 +0.042497 +0.18819 +0.59187 +0.45868 +0.16873 +0.1662 +139.72 +186.79 +3.7337e-06 +49.433 +0.029303 +31.187 +0.032739 +138.95 +141.53 +0.039169 +0.021171 +96.191 +0.034415 +279.51 +9.4937e-06 +9.06e-06 +0.0035584 +0.0060108 +0.0041609 +0.001312 +0.0015302 +0.077902 +0.036335 +0.030645 +8.9787e-06 +3.0569e-06 +3.3739e-06 +6.4366e-05 +0.011474 +0.0092952 +0.038766 +0.022884 +0.011224 +0.080374 +0.033245 +0.12729 +0.013458 +0.0071012 +0.0045467 +0.011903 +17.652 +80.177 +0.23096 +0.26308 +0.17565 +0.2424 +0.24437 +0.0060331 +1.1907e-05 +1.4167e-05 +0.0063106 +56.236 +0.010466 +0.018577 +0.01868 +0.0026522 +0.97063 +0.35778 +0.19674 +0.092407 +112.55 +0.058236 +427.52 +339.68 +0.040933 +0.010011 +70.096 +84.501 +240.21 +0.038151 +0.050434 +127.05 +219.32 +123.15 +104.16 +7.4024e-06 +1.9557e-06 +0.0042297 +0.0038302 +0.00098744 +0.0018558 +0.022957 +0.024825 +0.040776 +2.6271e-05 +6.502e-06 +1.26e-05 +1.5635e-05 +9.4413e-06 +0.025374 +0.053071 +0.034799 +0.01644 +0.16783 +0.064546 +0.16174 +0.040334 +0.0056769 +0.0054905 +0.020475 +22.488 +40.85 +0.063616 +0.15761 +0.31728 +0.59617 +0.13268 +0.086874 +0.0053337 +0.0052886 +6.6584e-06 +0.015557 +34.959 +0.021028 +0.011291 +0.0071816 +0.00056472 +0.34181 +0.15903 +0.054164 +0.060274 +0.0393 +0.22655 +446.59 +3.7064e-06 +0.016737 +0.02761 +79.237 +0.027967 +0.10589 +0.052769 +156.58 +192.82 +214.12 +38.687 +0.10934 +0.0037365 +0.0049628 +0.002863 +0.00091692 +0.0016203 +0.017719 +0.029533 +0.0095657 +6.1756e-06 +9.1459e-06 +2.4849e-05 +3.3318e-05 +8.6877e-06 +0.050108 +0.13498 +0.082309 +0.031656 +0.18614 +0.10653 +0.071859 +0.027141 +0.034654 +0.0092738 +0.014207 +18.405 +93.83 +0.050315 +0.035605 +0.30652 +1.4441 +0.39156 +0.17438 +0.03258 +0.0088939 +0.011841 +1.5326e-05 +0.014031 +65.22 +0.017492 +0.00481 +0.00080063 +0.16076 +508.08 +0.044018 +0.041611 +0.016717 +931.79 +0.021186 +63.426 +80.483 +0.026478 +84.784 +0.031827 +0.10251 +0.11968 +0.084618 +112.77 +106.32 +69.983 +0.0065734 +0.0026272 +0.0025831 +0.0039663 +0.0012807 +0.053347 +0.037967 +0.03682 +0.016427 +7.8384e-06 +1.1554e-05 +8.2844e-06 +3.1618e-05 +0.0553 +0.019853 +0.072376 +0.048441 +0.0442 +0.31428 +0.24716 +0.17733 +0.019373 +0.024107 +0.035873 +0.021115 +17.048 +76.688 +78.657 +0.074148 +0.045967 +1.2887 +0.62087 +0.3007 +0.038634 +0.21031 +0.0077422 +0.016082 +0.012879 +0.021744 +0.013182 +0.010189 +0.0011503 +0.17385 +0.08223 +0.10402 +0.017904 +0.010333 +0.046496 +0.0066585 +62.369 +83.384 +93.575 +134.94 +0.024889 +0.081264 +0.16276 +0.070911 +136.09 +0.037845 +0.049183 +0.0064011 +0.0029601 +0.0035975 +0.0029799 +0.066447 +0.029762 +0.051399 +0.072217 +0.014255 +2.0575e-05 +5.8017e-06 +1.5077e-05 +0.020783 +0.056063 +0.045459 +0.056335 +0.10585 +0.03519 +0.34963 +0.25015 +0.34376 +0.027015 +0.045724 +0.040905 +0.024973 +34.265 +0.021391 +127.98 +0.029757 +0.026289 +0.093864 +0.77301 +0.20403 +0.083885 +0.15422 +50.424 +92.187 +43.002 +0.02941 +0.021267 +0.011591 +0.00097039 +0.0012762 +0.1601 +113.38 +179.29 +0.013819 +51.486 +19.595 +69.385 +41.447 +0.030266 +0.13888 +0.04575 +0.061403 +0.068675 +0.063882 +132.12 +0.012063 +0.0077634 +0.0076019 +0.0051889 +0.0076537 +2.2543e-05 +0.028439 +0.035274 +0.036784 +0.054759 +0.038131 +1.3935e-05 +2.5902e-05 +0.020351 +0.0090192 +0.027314 +0.053877 +0.042409 +0.19835 +0.047324 +0.26273 +0.11954 +0.53536 +0.12061 +0.05329 +0.067363 +0.01657 +48.758 +42.437 +122.45 +0.031796 +0.027179 +0.075358 +0.10093 +7.2567e-06 +0.10322 +56.103 +93.453 +0.026802 +0.012612 +0.011086 +0.018938 +0.015068 +0.0033989 +0.0015462 +0.023163 +94.902 +114.04 +34.629 +39.016 +21.512 +0.056286 +0.047746 +0.052793 +0.15584 +0.19603 +0.02248 +0.052593 +0.041659 +0.019189 +0.0082503 +0.014025 +0.010687 +0.0057258 +2.1598e-06 +0.043139 +0.045588 +0.090479 +0.05503 +0.039387 +0.042339 +0.014538 +0.0051405 +0.010813 +0.0051997 +0.036221 +0.036475 +0.065658 +0.20866 +0.052873 +0.12896 +0.092389 +0.27321 +0.033125 +0.088478 +0.034121 +0.015531 +44.914 +65.539 +35.753 +0.017458 +0.045253 +0.077307 +0.067924 +0.026637 +0.014294 +29.305 +114.11 +0.01494 +0.01344 +0.012181 +0.050084 +0.050178 +0.0067229 +0.0031939 +0.046275 +102.51 +0.087949 +62.769 +16.659 +25.803 +0.0082324 +0.092846 +0.029168 +0.052237 +0.1145 +0.030636 +65.463 +0.070579 +0.013413 +0.015192 +0.017966 +0.0097813 +0.0024116 +1.0359e-06 +1.0067e-06 +0.1127 +0.12056 +0.065676 +0.06203 +0.026797 +0.021694 +0.0088884 +0.016588 +0.0098846 +0.037721 +0.018335 +0.070005 +0.37354 +0.05724 +0.11326 +0.073033 +0.04464 +0.0287 +0.063255 +0.039318 +0.043406 +47.519 +57.4 +25.324 +0.0083693 +0.093947 +0.04437 +0.094102 +59.94 +0.01158 +67.079 +139.76 +74.02 +0.013606 +0.026198 +0.070052 +0.15628 +0.014632 +0.012778 +0.059248 +79.122 +0.019022 +48.404 +13.892 +0.0056946 +0.0082659 +0.2114 +0.011517 +0.046311 +1.4831e-05 +0.024582 +0.019173 +0.018458 +0.03718 +0.032649 +0.025887 +0.0063576 +1.9762e-06 +0.043193 +0.015985 +0.047511 +0.10409 +0.1296 +0.084154 +0.040299 +0.048007 +0.0051768 +0.016451 +0.0035035 +0.021517 +1.8259e-05 +5.9901e-06 +2.2297e-06 +5.7724e-06 +0.12417 +0.051146 +0.071168 +0.060918 +0.06669 +0.046513 +0.02903 +59.259 +41.956 +0.0073955 +0.0047989 +0.038039 +0.03114 +0.043629 +0.050797 +55.954 +29.863 +0.024537 +0.02668 +0.027922 +0.033202 +0.066503 +0.1611 +0.17737 +0.43781 +0.0074561 +0.12729 +0.0070506 +56.291 +33.85 +0.010731 +0.0081716 +0.15655 +0.0187 +1.2202e-05 +6.2345e-06 +0.01361 +0.029382 +0.0095402 +0.03158 +0.090247 +0.011894 +0.01504 +0.0096962 +0.027384 +0.11425 +0.080158 +0.21568 +0.092856 +0.083416 +0.025139 +0.19959 +4.14e-06 +1.812e-05 +8.3538e-06 +4.9005e-06 +2.0769e-06 +3.7798e-06 +8.8131e-06 +1.1301e-05 +0.0484 +0.028766 +0.088471 +0.075157 +0.066148 +0.065977 +266.12 +0.0049447 +0.0041445 +0.0043865 +0.009055 +0.018994 +0.018965 +0.034072 +0.048529 +0.017236 +0.037618 +0.076183 +0.50975 +0.10035 +0.06528 +0.081282 +0.092085 +0.11896 +0.48195 +0.6391 +1.603e-05 +0.057867 +29.058 +0.020933 +0.014124 +0.0079787 +0.025455 +0.017346 +1.296e-05 +1.3914e-05 +6.7583e-06 +0.03059 +0.014543 +0.016887 +0.13697 +0.26472 +0.030719 +0.010553 +0.0045156 +0.11136 +0.070742 +0.18851 +0.044449 +0.050844 +0.033809 +0.076205 +5.2344e-06 +2.1712e-05 +1.9312e-05 +6.7138e-06 +7.9995e-06 +2.0295e-05 +4.5774e-05 +2.2191e-05 +7.8884e-06 +0.026933 +0.10231 +0.11645 +0.12576 +198.04 +0.096761 +0.0047455 +0.0073362 +0.0025471 +0.0136 +0.028871 +0.017745 +0.028767 +0.067817 +0.028027 +0.067645 +0.25625 +0.57779 +0.085892 +0.10965 +0.12236 +0.15139 +0.16923 +0.56947 +0.22471 +0.30849 +0.22468 +0.015506 +0.0093068 +0.024855 +0.0057639 +0.035378 +52.23 +0.02441 +2.585e-05 +9.6308e-06 +6.7533e-06 +0.029004 +0.024393 +0.15923 +0.3479 +0.1057 +0.072694 +0.14803 +0.071651 +0.035735 +0.098022 +0.043001 +0.038269 +0.035413 +0.04393 +1.1339e-05 +3.0329e-05 +9.4161e-06 +1.5305e-05 +9.2782e-06 +9.5161e-05 +2.9201e-05 +1.2462e-05 +0.00011793 +0.011613 +0.094925 +0.19695 +0.12493 +0.21141 +0.11405 +0.0058849 +0.011801 +0.0021139 +0.014271 +0.019698 +0.013761 +0.025994 +0.14824 +0.02386 +0.046289 +0.29063 +0.69538 +0.064948 +0.017838 +0.086376 +0.15433 +0.15599 +0.20295 +0.17315 +0.17874 +0.2129 +0.079517 +3.2003e-05 +0.002899 +0.0050484 +183.77 +0.014155 +36.712 +0.013445 +4.1731e-06 +0.0070702 +0.0051923 +0.021628 +0.099301 +0.2016 +0.20135 +0.043878 +0.12608 +0.074674 +0.044452 +0.035123 +0.032507 +0.054378 +1.6315e-05 +2.8269e-05 +0.00019011 +2.0684e-05 +1.1267e-05 +1.3311e-05 +2.9577e-05 +2.1237e-05 +1.4126e-05 +2.0694e-05 +0.11432 +0.028782 +0.10235 +0.15408 +0.15725 +0.19752 +0.13003 +0.0046896 +0.022361 +0.011088 +0.011906 +43.432 +0.023061 +0.036228 +0.11287 +0.037761 +0.07436 +0.085051 +0.04999 +0.0079682 +0.0081761 +0.047311 +0.13129 +0.15213 +0.16979 +0.10578 +0.14812 +0.013808 +0.023467 +0.048204 +12.556 +0.0070885 +255.71 +0.020812 +30.769 +129.53 +240.23 +0.014919 +0.16673 +0.036658 +0.056743 +0.13087 +0.24416 +0.042712 +0.020449 +0.03739 +0.03933 +0.067759 +16.234 +31.697 +1.9516e-05 +8.6463e-05 +4.0842e-05 +6.3739e-05 +1.1629e-05 +2.0011e-05 +1.2786e-05 +2.272e-05 +6.5623e-05 +1.45e-05 +0.029395 +0.043586 +0.10925 +0.20192 +0.21792 +0.21142 +0.09585 +0.0052593 +0.025785 +0.032696 +0.013197 +38.959 +0.023658 +0.036902 +0.063338 +0.0383 +185.26 +0.056276 +0.026444 +0.0046024 +0.007895 +0.042666 +0.034195 +0.075215 +0.21877 +0.18428 +0.16191 +1.7471e-05 +2.8696e-06 +6.9955e-06 +1.0603e-05 +19.823 +0.0010379 +1.0129 +54.023 +51.568 +159.02 +385.78 +0.091853 +0.060983 +0.067038 +0.12987 +0.10632 +0.030236 +0.023514 +0.0518 +0.059244 +0.084555 +1.1983e-05 +21.562 +11.008 +3.8875e-05 +1.9725e-05 +4.3545e-05 +4.583e-06 +7.7717e-06 +1.2011e-05 +1.0777e-05 +2.11e-05 +7.08e-06 +0.040234 +0.040473 +0.1402 +0.12991 +0.14551 +0.12313 +0.084234 +0.010915 +0.0852 +0.039277 +0.019578 +28.164 +0.042081 +0.05953 +0.09571 +0.013447 +157.01 +188.86 +0.03696 +0.0047113 +0.016511 +0.045018 +0.091871 +0.15598 +0.29835 +0.086686 +2.149e-05 +2.3093e-05 +2.5442e-06 +5.904e-06 +6.0502e-06 +4.2906e-05 +1.6602 +0.00020516 +0.0025895 +0.0018375 +445.8 +318.65 +261.02 +0.087863 +0.052394 +0.15837 +0.13037 +0.060672 +0.031582 +0.026327 +0.072026 +0.10014 +3.2825e-05 +1.9152e-05 +4.952e-06 +8.482 +0.0025594 +1.7304e-05 +1.0358e-05 +6.2688e-06 +3.2039e-06 +6.6776e-06 +1.1724e-05 +5.3414e-06 +0.033872 +0.035667 +0.067042 +0.06519 +0.12068 +0.25636 +0.22074 +37.137 +0.11334 +0.022794 +0.0099542 +0.025143 +0.042014 +0.067536 +0.019071 +0.014236 +91.786 +158.92 +0.038157 +0.003402 +0.028194 +0.040838 +0.10532 +0.15331 +0.008586 +0.0054615 +4.5374e-06 +1.8717e-06 +5.2816e-06 +1.5296e-05 +1.0399e-05 +2.6042e-05 +0.62185 +0.0010824 +0.0026506 +0.0033959 +0.0026444 +479.04 +214.65 +194.15 +0.043792 +0.15361 +0.10374 +0.01519 +43.198 +2.3796e-05 +2.6085e-05 +0.04409 +0.098714 +0.11102 +4.756e-06 +12.877 +0.0031724 +6.3343e-06 +1.1335e-05 +1.1661e-05 +3.3646e-05 +8.1637e-06 +4.4376e-06 +3.3464e-06 +0.039957 +0.063447 +0.037825 +0.025118 +0.2234 +0.31765 +0.50282 +0.011939 +57.411 +0.043228 +0.12144 +0.025953 +120.71 +0.039925 +0.01359 +0.012039 +0.028826 +0.15294 +0.071589 +0.0064168 +0.023529 +0.029625 +0.0067732 +0.0089798 +0.0080856 +0.0047942 +0.0084504 +1.6953e-06 +0.021784 +0.0025735 +0.011631 +0.0042733 +1.3064 +0.00082096 +0.95961 +0.0029043 +0.0087264 +658.77 +521.25 +81.406 +272.16 +0.009034 +0.01546 +363 +149.97 +109.57 +8.8524e-06 +3.5878e-06 +0.073884 +0.033929 +535.98 +0.0073325 +0.0041285 +6.2174e-06 +3.1851e-05 +3.1385e-05 +6.9932e-06 +2.9129e-06 +1.0351e-06 +0.10441 +0.013281 +0.015132 +0.019984 +0.021741 +0.18885 +0.13239 +1.1074 +26.303 +48.748 +0.061644 +0.16636 +0.037904 +131.81 +113.7 +0.021868 +0.016171 +0.038325 +0.15633 +191.71 +1.0046e-05 +0.0085418 +0.011494 +0.0211 +0.0097754 +0.004824 +0.00551 +118.73 +91.192 +0.0087969 +0.0018556 +0.0033902 +2.8698 +0.81065 +0.00049639 +3.049 +0.0010762 +0.019361 +0.024011 +359.22 +117.08 +322.33 +0.0088767 +1.2781e-05 +289.48 +139.67 +75.159 +0.018862 +6.2791e-06 +1.782e-05 +5.8732e-06 +1121.7 +0.010834 +0.0050934 +12.535 +3.4159e-05 +1.3706e-05 +1.5684e-05 +6.1521e-06 +268.77 +0.035627 +524.5 +0.013895 +0.010755 +0.040215 +0.10972 +0.095696 +0.23236 +32.481 +86.364 +221.58 +349.93 +0.048663 +309.34 +0.054968 +0.18848 +0.013124 +0.12016 +0.053986 +0.009043 +0.027183 +0.0040584 +0.010968 +0.019063 +0.004099 +0.0049597 +13.624 +0.033359 +0.015469 +0.013868 +0.0044656 +0.0036135 +5.8595 +1.4189 +0.00077976 +2.6897 +0.00057267 +0.005634 +0.015858 +204.42 +150.55 +1007.1 +1287.6 +0.010453 +1.353e-05 +5.1941e-06 +62.39 +112.68 +50.05 +137.15 +1.3671e-05 +5.8822e-06 +0.014974 +0.011095 +31.771 +34.431 +0.002511 +5.079e-06 +600.32 +195.61 +168.21 +0.21342 +207.73 +266.12 +0.021761 +0.059185 +0.11404 +0.25696 +173.14 +149.53 +95.446 +252.3 +0.18482 +0.003632 +0.05748 +0.091755 +0.14768 +0.078621 +0.026555 +0.011676 +0.025844 +0.0059159 +0.010483 +0.014492 +0.0069731 +7.3451 +38.808 +0.015951 +0.021409 +0.0014247 +0.0032715 +0.0038476 +6.2218 +2.694 +2.1703 +4.8302 +0.0016781 +0.048844 +161.59 +119.5 +248.43 +32.001 +12.561 +0.012678 +8.6474e-06 +1.0149e-05 +6.9468e-06 +356.92 +56.797 +191.92 +356.25 +33.916 +0.013244 +0.029297 +43.968 +0.0064735 +0.0038816 +0.0018292 +0.0021443 +200.86 +180.12 +37.087 +47.19 +171.32 +0.13179 +0.052364 +0.15254 +1.1599e-05 +226.88 +84.713 +209.84 +187.74 +47.906 +0.0053169 +0.10125 +178.03 +0.070098 +0.043349 +0.048672 +0.0042075 +0.015178 +0.0065416 +0.0092607 +0.010208 +0.0080555 +19.12 +39.266 +0.011236 +0.0040615 +0.0016801 +0.0018013 +0.0033207 +5.393 +2.2366 +2.1127 +3.5235e-06 +0.050252 +132.07 +0.01789 +0.014041 +125.63 +53.617 +0.015336 +0.014464 +3.4636e-06 +1.696e-06 +6.6269e-06 +0.003702 +0.00074215 +0.0003465 +0.0049714 +115.5 +2.156e-05 +9.7349e-05 +5.3516e-05 +0.0096312 +0.0075404 +0.005096 +0.0051966 +0.0024959 +139.59 +39.273 +21.322 +26.974 +0.020803 +16.401 +0.0025457 +0.0025383 +459.98 +193.42 +84.179 +0.014863 +0.020522 +0.00016084 +1.7917e-05 +0.047091 +0.07988 +9.0099 +0.011639 +0.002194 +0.016312 +0.018864 +0.0078267 +0.008216 +0.0087656 +39.06 +23.546 +19.356 +0.0063098 +0.0023338 +0.0041577 +0.0022427 +2.6698e-05 +7.227e-06 +0.27725 +419.66 +0.064392 +0.022564 +0.021787 +111.49 +102.2 +0.0012813 +0.0054096 +0.010334 +0.0029891 +0.0054058 +0.0057133 +0.011968 +0.0018702 +0.027322 +0.080463 +106.58 +0.025594 +0.050237 +96.077 +93.061 +0.01534 +0.011434 +0.0024718 +0.0015925 +0.011202 +65.381 +0.00073534 +11.733 +13.282 +6.6478 +0.0038782 +15.712 +0.0030385 +127.84 +127.34 +215.56 +308.83 +1.9847e-05 +2.0153e-05 +64.732 +0.03765 +13.315 +0.0073167 +0.0018185 +0.029767 +0.021272 +0.019979 +0.016616 +0.0089559 +29.07 +45.932 +19.608 +0.0035015 +0.0032335 +0.0069954 +0.0089352 +43.06 +794.49 +0.21245 +616.52 +233.67 +84.952 +66.395 +90.005 +0.0038698 +0.0015083 +0.0046053 +0.0010561 +0.0071144 +0.0091034 +0.008209 +1.2253e-05 +8.9744e-05 +7.6039e-06 +0.047782 +150.42 +0.040027 +0.044193 +0.019322 +101.92 +0.025701 +0.007282 +0.0028552 +0.0043439 +0.0052568 +0.0019558 +13.889 +7.4573 +0.012114 +5.241 +0.0037452 +7.2465e-06 +0.0048038 +0.058168 +339.08 +187.93 +108.02 +6.2185e-06 +59.321 +109.58 +54.059 +20.69 +20.313 +0.0041945 +0.027772 +0.040231 +0.015434 +0.014306 +101.48 +47.433 +18.83 +6.1647 +0.0041364 +0.0033542 +0.010677 +0.0082653 +60.257 +644.58 +0.1275 +389.42 +79.581 +97.037 +113.83 +3.2796e-05 +0.0047903 +0.004126 +0.0058991 +0.0031092 +0.017339 +1.605e-05 +1.2609e-05 +1.7936e-05 +6.4501e-05 +1.7449e-05 +7.4845e-06 +0.011357 +0.026054 +0.046495 +0.049473 +0.0031947 +0.023432 +0.0068536 +0.0063576 +14.332 +0.0025674 +0.0018393 +42.746 +2.4056e-06 +9.7862e-06 +7.3398e-06 +2.1122e-05 +4.1314e-05 +0.045136 +0.17495 +0.058969 +132.83 +216.55 +0.30233 +66.298 +211.07 +69.57 +31.831 +14.279 +0.0072048 +0.010779 +0.035736 +0.01957 +0.0185 +0.0037987 +12.863 +10.951 +0.013402 +0.013919 +0.0024233 +0.010973 +0.012686 +0.019837 +227.97 +0.053042 +93.271 +54.295 +1.226e-05 +0.0036767 +0.0077535 +0.0064672 +0.0048156 +0.0052085 +0.0031238 +1.0014e-05 +1.5015e-05 +1.0824e-05 +1.616e-05 +1.384e-05 +1.2659e-05 +9.8371e-06 +0.0069073 +0.010385 +0.027622 +0.038643 +0.0063309 +0.0024329 +0.0056721 +0.004697 +0.0026884 +0.0023512 +0.099877 +0.0034931 +0.008725 +6.7415e-06 +8.6134e-05 +7.6759e-06 +1.8656e-05 +0.004834 +0.0027538 +0.073654 +0.038183 +0.024649 +0.35456 +0.00012773 +276.96 +74.346 +88.19 +44.05 +0.012983 +21.31 +0.014347 +0.01571 +0.0070291 +0.0057068 +5.4335 +0.025604 +0.00955 +0.015079 +0.0019047 +0.010618 +0.014236 +0.06278 +0.085445 +0.048276 +4.1095e-06 +0.048213 +0.047989 +0.0034668 +0.0032237 +0.0011149 +0.002167 +0.0036577 +5.5264e-06 +3.0211e-06 +1.8916e-05 +4.1197e-06 +2.3012e-05 +2.5767e-05 +1.8535e-05 +0.0068385 +0.0034255 +0.011424 +0.055809 +0.037553 +0.0067427 +0.012455 +0.0066604 +0.013156 +0.0026306 +0.19267 +0.078501 +4.4827e-05 +4.744e-06 +0.0059846 +7.7496e-05 +0.00025935 +5.4714e-05 +0.0029221 +0.0017378 +1.7811 +0.020938 +0.025979 +0.086879 +0.17391 +304.37 +89.825 +61.692 +45.916 +25.783 +0.012624 +0.018837 +0.064838 +0.01727 +0.013804 +0.0066191 +0.018149 +0.0095369 +0.019956 +0.0022052 +0.0047261 +0.0074439 +315.74 +0.10138 +2.1778e-06 +3.919e-06 +0.033748 +0.10553 +0.005016 +2.1448e-06 +6.3402e-06 +0.001759 +0.0012243 +3.9517e-06 +3.8394e-06 +2.5718e-06 +1.0192e-05 +3.6288e-05 +3.2193e-05 +5.4223e-05 +0.0030582 +0.0016385 +0.0092145 +0.030481 +0.038342 +0.013895 +0.017972 +0.0016896 +0.0092312 +0.08609 +188.43 +0.06573 +0.029021 +7.433e-06 +7.3695e-06 +4.8337e-05 +8.7667e-05 +7.1858e-05 +0.0015272 +0.0010699 +2.4601 +3.7576 +0.016834 +0.11664 +0.084442 +0.05868 +0.023244 +0.060806 +0.011558 +28.472 +0.016109 +0.023107 +0.05207 +0.1039 +1.3616e-05 +1.8525e-05 +0.017162 +0.19275 +0.010485 +0.0039486 +0.003053 +0.011467 +0.059484 +0.017876 +7.1796e-06 +1.1671e-05 +0.075509 +0.17454 +0.018686 +2.4138e-06 +0.0019824 +0.0027499 +0.0018195 +0.019723 +3.0233e-05 +8.3009e-06 +5.889e-05 +7.9994e-05 +2.1453e-05 +2.8394e-05 +9.0087e-06 +8.9672 +7.2883 +0.014538 +0.017998 +0.014761 +0.021005 +0.0092321 +12.516 +0.061925 +0.029513 +0.05566 +0.037909 +179.09 +1.2375e-05 +4.0087e-05 +8.8514e-05 +3.2101e-05 +0.0013412 +0.00078664 +0.89624 +3.55 +0.001158 +0.0018667 +0.068114 +0.031161 +0.031688 +0.034253 +0.017922 +0.015769 +0.02662 +0.025209 +0.052556 +0.03488 +7.0855e-06 +1.1907e-05 +0.011789 +0.10873 +0.11017 +0.0049618 +0.0031649 +0.0045615 +0.022173 +0.013891 +0.022683 +0.10364 +0.087582 +0.21196 +0.021148 +1.8352e-06 +2.8232e-06 +0.0013519 +0.0036264 +0.016934 +6.6552e-06 +1.3617e-05 +6.378e-05 +0.45425 +0.072664 +9.015 +15.492 +7.6479 +9.1867 +0.015778 +0.0067765 +41.712 +0.017789 +0.0037449 +0.0044514 +1.4375e-05 +0.048775 +0.055801 +0.026523 +132.93 +0.13845 +8.0981e-05 +3.8665e-05 +3.3736e-05 +0.00047574 +0.0026617 +1.4158 +4.3822 +0.0014744 +0.014759 +0.0090592 +0.045643 +0.040808 +0.0081184 +0.0067094 +0.0031248 +0.0027379 +0.028148 +0.032456 +0.01769 +1.3061e-05 +0.0071589 +0.018124 +0.025415 +0.05735 +0.046688 +0.0020069 +0.0055479 +0.0070557 +0.013958 +0.012747 +0.14906 +0.078872 +0.1028 +3.8751e-06 +1.5453e-06 +0.0037693 +0.0020275 +0.0032217 +0.016726 +0.01259 +0.48675 +0.88775 +0.4744 +0.081733 +10.725 +17.797 +287.48 +0.019581 +0.025871 +0.0063075 +0.015637 +0.015081 +0.043178 +0.11872 +2.8357e-06 +0.037599 +0.083873 +0.02225 +118.42 +0.18708 +3.0641e-05 +1.4258e-05 +4.2786e-05 +0.0020021 +0.001169 +1.6405 +5.9521 +0.065216 +0.049208 +0.017488 +0.032801 +0.00511 +0.0097463 +0.0065539 +0.005523 +0.00077215 +0.0014614 +0.0037193 +0.010232 +0.25332 +0.058509 +0.018549 +0.02161 +0.065195 +0.052027 +0.030072 +0.0058958 +0.0081609 +0.0097312 +0.0075948 +0.14333 +0.090735 +0.12417 +5.995e-06 +7.0423e-06 +4.4508e-05 +0.0020826 +0.0059671 +209.31 +0.027465 +0.034665 +0.016915 +72.54 +87.041 +21.405 +4.7021e-05 +237.98 +67.236 +0.027363 +0.014682 +0.014806 +0.017988 +0.023227 +0.061369 +0.00094024 +9.6808e-06 +0.076082 +0.034581 +0.043079 +0.2224 +0.04594 +1.9736e-05 +1.455e-05 +0.0062836 +0.0018177 +0.020445 +0.012154 +0.063285 +0.086234 +0.0070088 +0.013822 +0.01298 +0.0047968 +0.0029455 +0.0066806 +0.0013889 +0.0014369 +0.0043484 +0.0036818 +0.085444 +0.1062 +0.025567 +0.020124 +0.055002 +0.52862 +0.029645 +0.015538 +0.0099316 +0.0040106 +0.016945 +0.074098 +0.13061 +0.11038 +2.5605e-05 +3.5843e-05 +631.81 +145.49 +0.22206 +250.34 +0.033034 +0.050935 +0.24141 +0.28197 +0.063536 +7.977e-06 +3.2448e-05 +156.01 +0.02221 +72.436 +0.022628 +0.012564 +0.034008 +0.02996 +0.043555 +0.00097728 +1.244e-05 +5.853e-06 +0.020618 +0.082709 +0.28664 +0.12577 +4.5667e-05 +3.6313e-05 +0.008373 +0.016717 +0.01901 +0.0097632 +0.029633 +0.033535 +0.0085533 +0.031068 +0.021924 +46.611 +0.0031289 +0.0061146 +0.0027941 +0.0013055 +0.0046185 +0.018323 +0.12135 +0.078446 +0.031882 +0.019595 +0.011056 +0.38652 +0.38912 +0.0085209 +67.213 +0.0034712 +0.011514 +0.051804 +0.087601 +0.17164 +128.5 +0.031565 +253.93 +111.75 +0.14814 +356.81 +0.026156 +0.058089 +0.3189 +0.25094 +1.0297e-05 +4.6378e-06 +7.4906e-06 +3.1121e-05 +0.014545 +0.033443 +0.053864 +0.039319 +0.0074503 +0.011416 +40.659 +0.00058721 +0.0011169 +1.3823e-05 +0.012464 +0.041885 +0.14295 +0.071015 +0.033569 +5.2072e-05 +0.0088318 +17.856 +0.015228 +0.012836 +0.0459 +0.024828 +0.011747 +0.045069 +1.7389e-05 +0.028808 +0.0027099 +0.011261 +0.0040598 +0.0028644 +0.0049515 +0.039432 +0.35664 +0.10991 +0.033589 +0.10983 +1.1366e-06 +0.32844 +0.26026 +0.4333 +0.012779 +0.00518 +0.026484 +0.049972 +112.02 +167.14 +130.93 +0.049329 +0.066056 +143.96 +0.027632 +0.0203 +0.021016 +0.039162 +2.0188e-05 +7.0393e-06 +4.9973e-06 +8.111e-06 +7.3274e-06 +9.5156e-06 +0.068182 +0.09426 +0.046585 +0.021713 +31.17 +19.505 +28.95 +0.00138 +0.00091091 +0.0037956 +0.0079985 +0.023487 +0.099919 +0.061019 +0.045425 +9.1811e-06 +25.726 +18.338 +0.012142 +0.0096061 +0.044639 +0.023738 +0.010194 +0.10255 +0.048933 +0.024265 +97.751 +0.015606 +0.0040599 +0.0067447 +0.014868 +0.10497 +0.29575 +0.15106 +0.063023 +0.10946 +0.01134 +0.17301 +0.19566 +0.2528 +0.10887 +0.012932 +0.063436 +110.8 +123.05 +142.8 +140.93 +0.0014374 +0.0017996 +0.012614 +0.028974 +0.060585 +0.021027 +0.0391 +4.2449e-06 +1.6027e-05 +1.6946e-06 +1.5409e-06 +6.8875e-06 +0.0043138 +0.029034 +0.081835 +0.064198 +0.048293 +40.88 +0.0077202 +0.00027069 +0.00040845 +0.00058779 +0.0015019 +0.0044188 +0.041464 +0.10839 +0.092165 +0.025123 +1.3003e-05 +27.107 +12.776 +26.091 +0.006445 +0.087614 +0.023404 +0.0056997 +0.060764 +0.049028 +0.0044936 +0.035453 +0.0080268 +0.0027515 +0.0089532 +0.015506 +0.090625 +0.090435 +0.13304 +0.05358 +0.15638 +0.37405 +0.12485 +0.20455 +0.15902 +0.25102 +0.0052265 +0.011112 +0.045963 +0.068351 +0.06856 +0.0015426 +0.001224 +0.0019932 +0.015057 +0.018968 +0.028629 +0.018983 +8.544e-06 +1.8577e-05 +2.3424e-06 +8.264e-06 +5.2771e-06 +0.0055624 +0.013485 +0.050488 +0.14894 +0.08274 +0.051705 +36.665 +0.00088171 +0.00019658 +0.00020627 +0.00076331 +0.0016331 +0.0023068 +0.096095 +0.2077 +0.077408 +0.013274 +3.6926e-05 +24.663 +33.114 +0.0054136 +55.316 +0.019602 +0.020528 +0.012546 +0.045206 +0.031396 +0.0058049 +0.0014138 +0.0053612 +0.0025246 +0.0081582 +0.026645 +0.12843 +0.11076 +0.13397 +0.10633 +0.1211 +0.0024905 +0.11642 +0.14913 +0.19463 +8.5308e-06 +1.9249e-06 +0.0048907 +0.075951 +0.14577 +0.0064646 +0.0014602 +0.0018561 +0.0035899 +0.0060252 +0.061188 +0.050613 +0.075337 +9.7946e-06 +2.5892e-06 +3.5392e-06 +4.5721e-06 +1.5179e-05 +0.017256 +105.08 +0.077641 +0.076526 +0.072035 +0.04536 +0.0016471 +0.0013518 +0.0034595 +2.6014e-06 +0.0010297 +0.000736 +0.0019813 +0.0039628 +0.2455 +0.19685 +0.017231 +5.2791e-05 +25.778 +0.0079914 +0.01069 +0.018164 +0.034836 +0.027177 +0.018058 +0.033908 +0.024003 +0.0081512 +0.0015007 +0.0058916 +0.0045367 +0.0070907 +0.012654 +0.13578 +0.073445 +0.08445 +0.1266 +0.11311 +0.0022526 +1.7569e-05 +0.053977 +0.057778 +80.143 +0.031093 +0.037576 +0.018161 +0.0875 +0.0074623 +0.028496 +0.029364 +645.05 +0.080333 +0.053064 +0.082542 +0.047009 +1.7569e-06 +5.5829e-06 +4.5731e-06 +6.3918e-06 +0.022091 +0.034571 +0.033574 +0.0768 +0.11872 +1.844e-05 +0.0010574 +0.0024056 +0.0011499 +0.0020784 +0.0018517 +4.9389e-06 +0.00072861 +0.00093063 +0.0031541 +0.0046434 +0.496 +0.011113 +2.8127e-05 +0.013279 +0.0088241 +0.017862 +59.163 +0.064015 +0.054134 +0.052228 +0.029469 +0.040511 +0.027326 +0.0038131 +0.042076 +0.0045479 +0.0091787 +8.5474e-05 +0.12727 +0.067976 +0.058239 +0.056789 +0.095526 +0.0032407 +0.088939 +0.13246 +0.035564 +0.029544 +0.022151 +0.055773 +0.004252 +0.007262 +30.686 +0.015001 +0.013333 +0.014363 +0.02123 +0.037014 +0.03098 +167.55 +2.3853e-06 +1.2282e-05 +2.4652e-05 +0.017219 +0.020816 +0.020422 +0.038375 +0.032765 +0.21806 +3.2733e-05 +0.00105 +0.0008815 +0.0020456 +0.0025376 +0.0013497 +45.111 +13.582 +0.0011425 +0.0018958 +0.0046069 +0.0019463 +3.0165e-05 +1.6494e-05 +0.012946 +0.007132 +0.13519 +64.298 +0.12418 +0.045546 +0.14058 +0.01864 +0.030111 +0.042231 +0.0077404 +0.016128 +0.023582 +7.0436e-05 +5.0665e-05 +3088.3 +0.05786 +0.02057 +0.037831 +0.024709 +0.17227 +0.10645 +0.086058 +17.81 +37.762 +0.025188 +0.014226 +0.0050057 +1307.5 +0.012392 +0.023385 +0.031728 +0.023024 +0.032335 +0.023727 +205.54 +0.040123 +139.88 +1.1989e-05 +0.039421 +0.021889 +0.014443 +0.022562 +0.023691 +3.0465e-06 +1.1116e-05 +9.5551e-06 +5.5263e-05 +0.0009072 +0.0018694 +0.0017051 +4.1645 +21.325 +9.471 +38.489 +0.0020847 +0.0042064 +0.001791 +0.00075684 +4.0808e-05 +0.013004 +0.014714 +0.059083 +388.48 +0.096755 +255.38 +142.68 +0.01413 +0.041169 +0.080286 +0.016296 +0.013436 +0.023006 +0.011762 +3.6558e-05 +0.63248 +0.016988 +0.029616 +0.047338 +0.033653 +0.18066 +0.20307 +0.017386 +18.791 +0.010026 +132.21 +0.011414 +4.0009e-05 +3.0926e-05 +35.262 +33.124 +0.015275 +0.011905 +0.019318 +0.021246 +0.036912 +1.836e-05 +152.65 +218.46 +281.49 +0.029201 +0.023121 +0.029395 +0.030489 +3.3314e-06 +1.0135e-05 +1.5282e-05 +6.723e-05 +0.00073363 +71.243 +20.087 +3.7887 +18.516 +12.847 +76.1 +22.186 +0.0024763 +0.001883 +0.00082548 +0.0030659 +0.0075263 +291.08 +162.5 +239.84 +0.10332 +0.058186 +150.77 +0.094034 +0.042019 +0.080028 +0.020965 +0.010109 +0.0041289 +0.014282 +0.0062857 +0.0059003 +0.017632 +0.011549 +0.030026 +0.030353 +0.37946 +0.0087911 +0.0060359 +0.006553 +33.665 +52.093 +0.010676 +10.314 +37.926 +41.202 +27.447 +0.010156 +0.0062362 +52.117 +0.014594 +0.023228 +2.8622 +1.921e-05 +1.6813e-05 +199.48 +183.16 +39.163 +0.019213 +0.031385 +1.5819e-05 +1.108e-05 +5.2321e-06 +0.025269 +27.912 +37.046 +10.361 +5.7562 +4.0662 +12.203 +40.135 +1.2091e-06 +0.0040135 +0.0028928 +0.0020715 +0.0035891 +598.08 +171.34 +174.55 +139.82 +0.087704 +141.27 +0.0065902 +0.14829 +0.22852 +0.063528 +0.030504 +0.013016 +0.0038112 +0.009783 +0.012799 +0.0046226 +0.0096815 +0.0074322 +0.0052556 +0.014949 +0.0025225 +0.0072068 +0.007247 +43.175 +47.352 +1.6202e-05 +11.112 +11.771 +22.597 +69.732 +0.16305 +0.2434 +0.012168 +0.045696 +68.245 +0.013049 +0.0029916 +5.8132e-05 +6.7805e-06 +0.0057089 +0.02393 +0.1148 +0.013689 +33.703 +0.0079663 +1.3417e-05 +1.9175e-05 +1.2631e-05 +78.259 +58.498 +19.021 +2.7162 +4.6395 +12.174 +2.3232e-06 +2.1142e-06 +2.93e-06 +0.0021144 +0.0022945 +0.008737 +575.26 +274.58 +183.68 +200.6 +220.76 +0.014187 +0.073614 +0.056049 +0.312 +0.035412 +0.055635 +0.0073302 +0.0059177 +0.012623 +0.010126 +0.0032884 +0.0073783 +0.0039784 +0.0042599 +0.0046013 +0.005569 +0.006369 +0.012789 +108.33 +13.276 +14.585 +22.998 +0.0047136 +10.915 +8.6091e-06 +1.3785e-05 +0.15292 +0.0083681 +0.091835 +0.032961 +0.023879 +0.0034485 +0.038483 +4.0877e-05 +1.1751e-05 +0.018483 +0.085347 +0.093713 +0.062527 +0.003009 +0.0098193 +0.0066893 +1.6512e-05 +213.74 +75.072 +71.933 +4.9597 +2.2769e-06 +29.126 +8.2615e-06 +3.0556e-06 +3.9495e-06 +7.6921e-06 +3.297e-06 +1.3081e-05 +564.02 +237.22 +171.36 +39.185 +29.134 +0.0083986 +0.018847 +972.23 +0.22854 +0.042458 +0.053396 +0.08224 +0.079061 +0.019068 +0.053097 +0.10253 +0.051729 +0.005751 +0.004647 +0.003237 +0.0068906 +10.727 +0.0046614 +0.0037095 +0.0022332 +12.502 +38.686 +9.9182 +17.926 +6.1617e-06 +1.6163e-05 +8.5615e-06 +0.0061675 +0.22461 +0.052912 +0.019644 +0.0070135 +0.050634 +541.16 +0.032168 +0.084286 +0.056803 +0.072248 +0.034002 +1.1562e-05 +4.2642e-05 +7.8126e-05 +0.0052659 +0.006041 +34.602 +41.557 +5.562 +1.3211e-06 +1.47e-06 +6.7439e-06 +5.5727e-06 +9.4388e-06 +1.7427e-05 +2.9811e-06 +9.0882e-06 +728.4 +249.2 +0.061791 +23.437 +32.988 +0.0048021 +0.020506 +0.015711 +34.949 +0.014726 +0.062243 +0.067723 +0.044727 +0.036681 +0.059954 +0.099903 +0.13508 +0.043052 +0.0054272 +0.0048573 +34.771 +25.404 +0.0086391 +0.00097096 +0.000648 +9.0249 +0.0060887 +5.5544e-06 +1.1493e-05 +2.9547e-05 +1.0904e-05 +4.6772e-06 +49.366 +254.54 +231.18 +0.015577 +0.021923 +0.062098 +0.066822 +0.13211 +0.065943 +0.082387 +0.029502 +0.022758 +3.3073e-05 +2.1478e-05 +2.1812e-05 +8.8187e-05 +0.0087352 +0.0094317 +0.0079113 +16.752 +7.7971 +1.1826e-05 +4.63e-06 +2.0368e-05 +1.5933e-05 +2.0266e-05 +7.8118e-06 +1.7134e-05 +380.77 +0.069496 +0.089892 +39.275 +0.0098952 +0.001979 +0.027499 +0.0067228 +0.0061322 +0.040721 +0.024226 +0.073827 +0.035711 +0.025049 +0.063353 +0.10358 +0.11937 +0.0066531 +35.858 +2.6822 +19.644 +39.584 +0.01094 +0.0020582 +0.0017322 +5.7799 +2.5694e-05 +3.0751e-05 +2.1913e-05 +1.033e-05 +3.2373e-06 +1.699e-05 +111.17 +0.11022 +0.089991 +0.031019 +0.011645 +0.047168 +0.2196 +2.517e-05 +0.053989 +0.036752 +0.027907 +0.02483 +0.012078 +0.00014623 +5.6745e-05 +1.2788e-05 +1.6452e-05 +2.811e-05 +0.0069861 +0.01209 +7.2599 +5.7783e-06 +5.3848e-06 +3.4549e-05 +3.0368e-05 +1.1394e-05 +1.3671e-05 +4.9957e-06 +0.45776 +406.69 +0.11691 +0.18653 +0.13001 +6.6137 +0.02764 +0.0038201 +0.011211 +0.01418 +0.012127 +0.081269 +0.033975 +0.034072 +0.17498 +0.12322 +0.079076 +35.704 +10.681 +5.9377 +16.738 +27.463 +0.0083599 +0.0039487 +0.0014554 +8.6833 +9.5537e-06 +3.4267e-05 +1.2202e-05 +7.2427e-06 +9.2746e-06 +1.0909e-05 +5.5135e-06 +338.9 +315.91 +0.065998 +0.01181 +0.028091 +0.19904 +1.0124e-05 +9.5934e-06 +0.018643 +0.017301 +0.023154 +0.01623 +0.016033 +50.999 +1.9699e-05 +8.4227e-06 +1.2183e-05 +0.0050555 +0.011597 +0.023976 +0.020239 +0.056523 +5.0472e-06 +1.3295e-05 +1.5889e-05 +9.15e-07 +6.4198e-06 +1.6449e-05 +0.22564 +0.093602 +0.079529 +0.1198 +0.034632 +0.072252 +0.0022909 +0.0074286 +0.041716 +0.01135 +0.045331 +0.020637 +0.072765 +0.13597 +0.2645 +0.026694 +33.358 +14.014 +10.617 +9.9351 +27.761 +0.0093318 +0.0040804 +0.0022519 +0.0073753 +0.020211 +1.8169e-05 +1.0232e-05 +8.8391e-06 +2.4022e-05 +0.039276 +0.15374 +990.98 +463.9 +142.01 +0.03276 +0.056955 +0.050692 +0.018199 +0.05042 +2.0371e-05 +0.010807 +0.020552 +0.016371 +0.020954 +0.023548 +0.03087 +0.06155 +2.5609e-06 +1.0415e-05 +0.001516 +0.0018586 +0.020675 +0.061482 +0.11183 +6.1337e-06 +7.9986e-06 +6.0736e-06 +7.9614e-06 +2.289e-05 +0.014487 +0.0046092 +20.664 +0.13664 +0.038028 +0.020068 +0.031558 +0.011199 +0.020948 +0.016324 +0.027706 +0.029544 +0.021927 +0.20846 +0.30527 +0.013212 +52.959 +27.854 +19.975 +16.228 +0.0046612 +0.0078561 +0.0034317 +0.014696 +0.0086729 +0.020564 +0.0055683 +7.9042e-06 +1.4217e-05 +1.425e-05 +0.07398 +0.13168 +776.39 +1358 +693.99 +0.038075 +0.013558 +0.037973 +0.036782 +0.056019 +0.097025 +0.0071486 +0.0079599 +0.0097699 +0.0082987 +0.010501 +0.088296 +0.048995 +0.059938 +0.069806 +0.045394 +0.0022206 +0.007562 +0.033574 +0.058702 +0.028235 +4.0447e-06 +8.8218e-06 +1.6329e-05 +23.341 +23.217 +0.011972 +0.0012219 +1.7718 +0.015603 +0.027835 +0.037606 +0.043736 +0.019064 +0.012254 +0.056525 +0.068291 +0.035968 +0.27076 +7.2793e-06 +28.772 +34.228 +22.52 +10.457 +0.0060153 +0.0026578 +0.0047649 +0.02826 +0.01303 +0.0084802 +0.01403 +0.006709 +9.1767 +5.9206e-06 +0.074248 +262.75 +191.71 +421.84 +1224.4 +278.96 +0.13369 +0.032374 +0.025424 +0.024176 +0.066121 +0.13134 +0.0043589 +0.0042922 +0.0066418 +0.0049555 +0.013498 +0.0060055 +0.11973 +0.07616 +0.098642 +0.039933 +0.048213 +0.01622 +0.040789 +0.10523 +0.030401 +6.3463e-06 +4.7209e-06 +2.4671e-06 +0.0063195 +20.009 +15.549 +0.0053939 +0.011337 +42.286 +0.011471 +0.022929 +0.10294 +0.16123 +0.53874 +0.50039 +72.956 +0.93807 +0.092337 +15.05 +56.047 +83.307 +34.018 +20.353 +17.732 +0.0015583 +0.0025626 +0.0020198 +0.02229 +0.0023408 +0.0083357 +0.004815 +14.674 +1.6764e-05 +196.92 +152.99 +75.154 +158.26 +246.89 +0.076349 +0.13254 +0.044161 +0.038469 +0.025212 +6.2489e-05 +5.0631e-06 +0.0041746 +0.0043172 +0.0074317 +0.0060967 +0.0055314 +0.53342 +0.38 +0.29968 +0.11195 +0.026093 +0.02315 +0.030787 +0.02133 +0.044396 +0.039229 +2.2197e-05 +8.749e-06 +3.0671e-06 +0.072722 +37.315 +25.201 +0.0081797 +87.789 +74.109 +0.011511 +0.029174 +0.088173 +0.26828 +0.4328 +0.55403 +0.53234 +25.938 +84.416 +24.48 +53.763 +45.526 +19.73 +33.766 +9.7831 +0.0010206 +0.0019956 +0.011773 +0.010903 +0.0057502 +0.0053756 +0.0037745 +24.247 +115.74 +197.74 +202.33 +140.41 +168.84 +340.69 +0.046074 +0.10748 +0.04996 +0.028392 +0.03955 +370.96 +0.16382 +0.0053248 +0.011271 +0.0069911 +0.01289 +0.0060747 +0.43096 +0.28656 +0.23283 +0.062418 +0.018571 +0.035375 +0.023971 +0.025309 +0.028623 +1.082e-05 +1.3238e-05 +6.4563e-06 +3.965e-06 +0.033488 +151.79 +0.008681 +0.01783 +199.19 +0.10755 +245.49 +0.057713 +0.17749 +189.75 +0.01649 +0.54709 +0.89435 +0.37429 +0.1345 +34.572 +43.203 +33.642 +32.296 +26.864 +12.331 +2.1306 +0.0020637 +0.0043597 +0.0089798 +0.0075311 +0.0074725 +0.011686 +0.025926 +136.7 +0.049877 +150.85 +211.44 +157.11 +4.1684e-05 +0.13015 +0.094147 +0.10151 +0.025164 +0.1433 +474.61 +0.13983 +0.0040127 +0.019885 +0.0076973 +0.012006 +0.73882 +0.38355 +0.025131 +0.024494 +0.061507 +0.030195 +0.053592 +0.037412 +2.0206e-05 +5.0042e-06 +5.6924e-06 +2.6609e-05 +8.7839e-06 +2.2109e-06 +0.036845 +131.47 +0.011109 +0.013205 +276.41 +0.08089 +0.10196 +159.35 +644.79 +0.043563 +0.014487 +0.023064 +1.0643 +0.58983 +0.20261 +12.034 +56.541 +41.672 +50.646 +61.145 +12.635 +1.5884 +0.0022695 +0.0035925 +0.012113 +0.061233 +0.01881 +0.0057532 +0.0293 +171.11 +162.28 +122.42 +173.89 +1.5926e-05 +8.1058e-05 +4.284e-06 +0.080355 +0.055501 +0.043707 +269.07 +413.57 +0.015961 +0.0068162 +0.025439 +0.0088432 +1.425 +0.28364 +0.0031255 +0.028521 +0.032357 +0.021499 +0.0090656 +8.04e-06 +1.4419e-05 +1.4268e-05 +1.3e-05 +5.3223e-06 +1.5144e-05 +2.9863e-05 +3.5042e-06 +0.049288 +0.021098 +0.0094369 +0.030537 +198.71 +0.072163 +354.41 +146.93 +131.55 +0.12183 +0.009778 +0.0075163 +0.49845 +0.40913 +0.0060795 +9.5034 +37.428 +59.557 +52.983 +62.002 +11.195 +1.089 +2.7393 +0.0018701 +0.013401 +0.02315 +0.0097791 +0.0070328 +0.027916 +165.56 +245.06 +0.034967 +169.18 +8.5929e-05 +4.2366e-05 +1.8717e-05 +0.10021 +0.031558 +200.06 +0.10314 +0.012497 +0.0086975 +0.0097122 +0.021714 +0.0089199 +0.087274 +0.012694 +0.0053245 +0.054653 +0.057212 +0.02296 +5.9899e-06 +1.7263e-06 +1.6696e-05 +1.6621e-05 +3.571e-05 +1.8074e-05 +2.2769e-06 +4.7176e-06 +2.3812e-05 +0.043436 +0.015143 +11.441 +0.021813 +264.8 +0.078261 +402.86 +0.16959 +301.94 +0.035773 +0.063414 +14.945 +0.53972 +0.54698 +0.0046838 +9.9356 +19.845 +55.532 +31.735 +67.72 +10.58 +4.4341 +6.2205 +0.0027536 +0.0024715 +0.012173 +0.011363 +0.0055759 +0.032364 +0.020689 +0.076323 +4.2954e-05 +1.2588e-05 +3.8625e-05 +2.9449e-05 +4.3779e-06 +2.7847e-05 +0.054334 +138.06 +0.11478 +0.023892 +0.0061311 +0.018105 +0.020856 +0.050839 +0.033902 +0.017528 +0.0125 +49.387 +4.3501e-06 +2.866e-06 +6.2457e-06 +4.0213e-06 +1.1443e-05 +2.1913e-05 +1.1669e-05 +4.374e-06 +1.6654e-06 +1.7226e-05 +6.2289e-06 +0.02472 +0.021831 +20.208 +0.020026 +0.061229 +0.024255 +194.21 +0.24241 +343.06 +285.82 +41.211 +16.056 +0.77545 +23.794 +28.374 +9.7707 +23.104 +31.679 +29.515 +56.297 +6.946 +5.0019 +0.0023345 +0.0033799 +0.005045 +0.0064834 +0.015759 +0.0042568 +0.026119 +55.778 +0.061425 +3.3103e-05 +2.8102e-05 +1.3799e-05 +1.5294e-05 +7.3055e-06 +8.494e-05 +38.167 +0.046239 +0.058203 +0.017923 +0.012921 +0.098313 +0.076344 +0.013708 +0.034552 +0.00889 +0.016544 +0.0027223 +1.583e-05 +9.6839e-06 +7.1621e-06 +4.3791e-06 +5.0473e-06 +6.1135e-06 +2.2685e-06 +8.3898e-06 +3.8899e-06 +7.427e-05 +6.071e-05 +0.026754 +59.492 +20.926 +0.0084708 +0.039057 +0.070821 +0.29341 +0.17214 +335.05 +369.22 +52.314 +0.93867 +32.544 +41.897 +22.614 +7.9546 +36.198 +32.599 +26.928 +103.48 +22.306 +20.51 +0.0034298 +0.0028465 +0.0048125 +0.0070851 +0.0096992 +0.0061976 +0.037184 +0.15751 +0.10942 +0.03421 +7.7362e-06 +7.6971e-06 +5.553e-06 +1.2666e-05 +88.703 +75.897 +0.038244 +0.048303 +137.69 +0.0085039 +0.049806 +0.081014 +0.010307 +0.02082 +0.016199 +0.012581 +1.919e-05 +1.2191e-05 +3.7021e-06 +2.9284e-05 +5.2602e-06 +3.2042e-05 +4.6684e-06 +1.262e-05 +4.4467e-05 +6.4395e-05 +6.337e-06 +2.208e-05 +0.022339 +0.027376 +20.286 +0.0070992 +0.050643 +0.085167 +0.23962 +563.29 +0.0062199 +0.0028433 +0.073263 +229.54 +66.044 +70.643 +18.305 +8.0687 +26.171 +21.126 +61.157 +107.32 +17.586 +21.272 +0.033452 +0.0060353 +0.0098742 +0.0099331 +0.014246 +0.0037093 +0.018775 +0.12275 +0.15631 +0.030069 +6.4358e-06 +1.8656e-05 +0.0081927 +0.0046866 +75.04 +0.029185 +238.38 +220.75 +0.06675 +0.020608 +0.041379 +0.013957 +0.010127 +0.0034505 +0.010677 +1.0019e-05 +1.1337e-05 +8.1098e-06 +1.3903e-05 +1.7152e-05 +5.7469e-06 +2.7896e-05 +8.9418e-06 +7.3589e-05 +3.2431e-05 +6.4671e-05 +3.4203e-05 +6.5661e-06 +0.016032 +0.008067 +36.993 +0.017951 +0.035025 +0.5073 +0.35334 +0.011599 +47.384 +2431.8 +563.79 +194.58 +25.323 +91.122 +30.213 +11.655 +25.942 +48.455 +78.928 +58.638 +26.934 +0.0039924 +0.022573 +0.0042995 +0.0078674 +0.0053808 +0.0094261 +0.0088364 +0.037394 +0.099686 +0.13418 +0.046436 +3.9879e-06 +0.0065058 +0.0091046 +0.0081726 +0.038179 +0.14955 +0.068313 +0.11238 +0.051743 +48.951 +0.0024442 +0.0040156 +0.0038388 +0.002515 +0.0094066 +2.4743e-06 +6.8258e-06 +1.9848e-05 +9.3696e-05 +0.00014281 +1.1725e-05 +1.5148e-05 +1.642e-05 +2.3464e-05 +2.2145e-05 +1.9224e-05 +0.0002505 +7.0668e-05 +0.020105 +0.0090126 +38.064 +0.119 +0.077707 +0.48997 +0.067877 +0.11302 +2.0386 +3178.7 +0.37702 +233.76 +53.02 +47.374 +50.522 +20.021 +23.034 +29.015 +54.767 +0.0018197 +0.0054624 +0.0044979 +0.0083368 +0.0060242 +0.0073634 +0.0065679 +0.007081 +0.053725 +0.045141 +0.071955 +0.10997 +0.034066 +0.032284 +0.0040488 +0.061653 +0.38164 +348.87 +367.37 +0.041671 +0.10443 +2719 +0.0070761 +0.0017786 +0.0076351 +0.0027222 +0.0010547 +0.00169 +2.1039e-06 +4.5338e-06 +9.5938e-06 +1.3353e-05 +3.1105e-05 +5.5649e-06 +8.3421e-06 +4.4455e-06 +1.6204e-06 +1.4049e-05 +3.4422e-05 +9.559e-06 +3.4635e-05 +0.014015 +0.19443 +0.083685 +0.035934 +0.038013 +0.090241 +0.08961 +0.091653 +0.026012 +1656.2 +596.99 +146.32 +115.47 +33.427 +56.911 +15.006 +41.318 +49.682 +0.0067841 +0.0017139 +0.0069179 +0.0042488 +0.0052427 +0.0084819 +0.010317 +0.0044679 +0.0083167 +0.034259 +0.11818 +0.037838 +0.11053 +0.041063 +2438.8 +870.57 +0.062733 +478.45 +217.58 +0.10026 +9.602e-06 +6.3524e-06 +1933 +0.010358 +0.0026237 +0.0086196 +0.0051087 +0.0025939 +0.0031543 +1.4291e-06 +4.506e-07 +3.0525e-06 +1.5593e-05 +1.8315e-05 +4.3413e-06 +2.4672e-05 +4.6868e-06 +1.4889e-05 +1.8599e-05 +0.00019303 +3.7693e-05 +4.1698e-05 +0.063052 +0.094482 +0.0097564 +0.02966 +55.713 +296.05 +0.1218 +0.16532 +0.046928 +993.74 +452.93 +133.18 +99.132 +0.012385 +40.833 +11.768 +47.938 +7.3861e-05 +0.003021 +0.0040968 +0.0027758 +0.0059848 +0.004637 +329.62 +0.0043889 +0.0098104 +0.0040548 +0.023548 +0.066996 +0.034812 +0.037051 +0.024304 +1442.3 +1082.1 +172.93 +0.12566 +3.0354e-05 +1.7953e-05 +2.9701e-05 +5.3853e-06 +1768.9 +0.0050044 +13.877 +0.0047816 +0.0042807 +0.0069952 +0.010656 +3.4318e-05 +2.5863e-06 +1.704e-05 +1.3901e-05 +9.5444e-06 +9.2367e-06 +1.2837e-05 +1.8696e-06 +1.6011e-06 +4.4065e-06 +1.034e-05 +6.8349e-06 +1.808e-05 +0.061998 +0.031202 +0.012954 +0.027942 +0.021625 +36.986 +0.098396 +0.39449 +0.054357 +1039.8 +0.17942 +94.57 +109.47 +0.012876 +94.88 +12.22 +35.449 +0.00012723 +0.0046693 +0.0017538 +0.0073975 +0.010889 +0.009922 +0.01258 +0.011348 +0.022724 +0.0075975 +0.02025 +0.090264 +0.043451 +0.024182 +2210 +1515.2 +0.5326 +0.0098017 +20.953 +1.6565e-05 +2.5871e-05 +7.7979e-06 +7.7727e-06 +0.020277 +0.0044165 +22.449 +0.0052991 +0.0037051 +0.0079419 +0.024529 +56.539 +2.2691e-06 +1.3789e-06 +1.4137e-05 +5.3556e-06 +1.0356e-05 +1.1882e-05 +1.0259e-05 +1.9621e-06 +4.3758e-06 +2.0601e-05 +1.1421e-05 +4.2741e-05 +332.88 +609.11 +0.24511 +0.031358 +0.059671 +0.012566 +0.013584 +0.044203 +0.077845 +0.081021 +221.43 +94.604 +114.79 +0.010618 +52.107 +25.404 +0.0092843 +0.0017735 +0.0065789 +0.0039076 +0.0056094 +0.016355 +0.016485 +0.049557 +0.012521 +0.026944 +0.011881 +0.024201 +0.092905 +0.071676 +1314.3 +1462.9 +0.4573 +0.014831 +0.0096322 +0.0059475 +4.2397e-06 +7.6226e-06 +1.3975e-05 +0.045651 +35.53 +10.329 +20.124 +0.0045391 +0.0034866 +0.0059594 +31.422 +44.248 +1.0363e-05 +5.6511e-06 +1.4809e-05 +9.8921e-06 +3.1666e-06 +2.5205e-06 +1.1921e-05 +4.5407e-06 +9.4984e-06 +2.3079e-05 +9.6631e-06 +1.0193e-05 +0.49248 +0.46957 +0.029495 +0.38565 +0.030247 +0.0031979 +0.0065641 +0.046215 +0.070475 +0.091791 +0.057557 +52.592 +69.486 +0.017622 +29.441 +24.222 +33.341 +0.0019508 +0.0034909 +0.0014136 +0.0030208 +0.018659 +0.0073339 +87.465 +0.027649 +0.024013 +0.041812 +0.023408 +0.060779 +827.23 +1476 +839.83 +1418.8 +788.08 +0.012868 +0.0046913 +7.26e-06 +7.2401e-06 +0.084144 +0.064664 +0.022438 +0.0045655 +18.145 +0.0067441 +0.035593 +0.05719 +53.744 +17.637 +0.01979 +1.3627e-05 +3.0573e-05 +1.1765e-05 +6.7013e-06 +1.8219e-06 +1.6733e-06 +5.7497e-06 +6.4122e-06 +1.3514e-05 +9.0312e-06 +6.6371e-06 +1.4163 +0.75429 +283.02 +0.032296 +2.3517e-05 +0.0030915 +30.034 +0.037611 +0.033724 +0.0723 +0.10562 +0.076133 +0.017687 +0.0055933 +31.283 +24.569 +28.914 +21.535 +0.002172 +0.0010677 +0.0022403 +0.015335 +0.0063851 +0.0097804 +0.016595 +0.029634 +0.049623 +0.01847 +0.041273 +0.0043664 +1680.6 +1200.9 +558.1 +803.77 +0.00598 +0.0050525 +11.609 +232.69 +0.057289 +0.14759 +0.033699 +0.011505 +0.06499 +0.2193 +0.024561 +0.07441 +0.019127 +25.486 +0.017042 +2.6531e-06 +1.137e-05 +2.7563e-06 +2.8579e-06 +1.7583e-06 +1.7441e-06 +5.683e-07 +2.4632e-06 +4.0253e-06 +1.3335e-05 +1.8874e-05 +1.4495 +1.657 +160.56 +0.0098258 +0.099854 +0.065323 +6.2389 +0.00090748 +0.036011 +0.13028 +0.18285 +0.1244 +0.093362 +0.0055069 +20.796 +12.1 +10.903 +36.408 +0.0010116 +0.001508 +0.0036442 +50.446 +0.01222 +0.012415 +0.027844 +0.042585 +0.046823 +0.015497 +0.012634 +0.0023185 +0.0050345 +0.37127 +439.81 +538.15 +416.05 +0.0072252 +15.336 +0.017873 +0.055167 +0.15856 +0.033167 +0.034835 +0.035349 +0.12771 +0.063525 +0.039283 +0.0091123 +28.824 +68.242 +6.421e-07 +4.9285e-06 +4.4429e-06 +8.224e-07 +4.7792e-06 +6.8893e-06 +1.7327e-06 +3.9469e-06 +8.043e-06 +1.3022e-05 +8.2486e-06 +1.5401 +1.2469 +0.0016882 +0.014176 +0.07348 +0.29301 +0.032375 +5.2506e-05 +0.0021982 +0.16934 +0.17276 +0.18952 +0.095711 +0.10749 +21.077 +15.804 +13.677 +63.026 +12.639 +0.0010354 +0.0019661 +0.0079071 +0.022231 +0.0067117 +0.02187 +0.019349 +0.023843 +0.029685 +0.0085012 +0.0040904 +0.0059337 +0.34102 +510.15 +389.01 +634.63 +879.12 +0.0020937 +0.012349 +0.0062511 +0.014119 +0.03273 +0.022118 +0.024025 +0.061272 +0.033089 +0.023397 +0.0080032 +18.307 +34.94 +84.42 +3.5713e-05 +2.9346e-06 +2.7064e-06 +3.5857e-06 +4.5525e-06 +6.328e-07 +4.8262e-06 +7.2376e-06 +8.9183e-06 +2.5603e-05 +1.186 +1.8 +0.0084076 +0.011248 +0.047124 +0.195 +0.023046 +0.022641 +0.023352 +45.639 +0.13109 +0.16637 +0.077952 +0.075812 +0.040568 +19.882 +19.532 +25.527 +17.65 +18.061 +5.6335 +0.023433 +0.010495 +0.0030056 +0.0012884 +0.033023 +0.036601 +0.052689 +0.013022 +0.0041979 +0.0039877 +24.928 +201.7 +527.64 +401.64 +854.85 +0.0073871 +0.0095442 +0.013127 +0.0078909 +0.029433 +0.027398 +0.039663 +0.04835 +0.04937 +0.02446 +0.013736 +25.374 +0.016583 +54.588 +2.4078e-05 +4.7571e-06 +4.2202e-06 +1.1999e-05 +3.037e-06 +9.228e-07 +2.1816e-06 +3.0977e-06 +1.7975e-05 +2.4829e-05 +0.00074315 +2.1879 +15.88 +1.9791 +0.029388 +0.48638 +0.09283 +0.011259 +0.018304 +0.0021641 +0.0015022 +0.071713 +0.16148 +0.062928 +0.054228 +0.014276 +21.905 +19.91 +5.4998 +18.334 +12.542 +17.945 +0.0043447 +0.003707 +0.0016375 +0.045518 +0.060162 +0.19838 +0.012705 +0.0063564 +0.00091131 +24.58 +0.0065859 +43.557 +199.79 +924.86 +0.49753 +83.282 +0.018154 +0.0086337 +0.0081146 +0.029329 +0.032772 +0.10738 +0.051255 +0.03471 +0.013498 +47.328 +0.02653 +5.4571e-06 +1.8742e-05 +8.2125e-06 +3.3194e-06 +8.1653e-06 +4.9311e-06 +5.8793e-06 +2.0303e-06 +6.7323e-06 +1.3689e-05 +2.0344e-05 +0.0013834 +2.9316 +14.666 +3.7547 +4.8767 +0.49656 +0.16595 +0.014105 +0.019306 +0.0035968 +0.0034877 +0.0052472 +0.13441 +0.04939 +0.06127 +56.406 +15.875 +11.952 +6.1056 +10.126 +0.0015054 +12.496 +0.010628 +0.0051689 +0.0014346 +0.053601 +0.067232 +0.10508 +0.0098978 +0.010755 +0.0015314 +20.269 +0.0025825 +27.169 +0.055162 +1172.4 +0.22114 +89.246 +42.457 +22.288 +0.0084463 +0.049794 +0.032186 +0.079851 +0.099735 +0.024592 +0.020791 +0.028935 +6.7189e-06 +1.2025e-05 +1.1858e-05 +3.864e-05 +1.0523e-05 +3.428e-05 +1.8746e-05 +3.4576e-06 +8.9765e-06 +5.9297e-06 +1.0473e-05 +1.5225e-05 +0.001386 +3.6964 +9.3979 +2.6759 +0.032304 +0.013471 +0.014597 +0.045124 +0.0059115 +0.0055685 +0.0085474 +0.0088555 +0.0015423 +0.055567 +0.047914 +38.415 +45.188 +12.348 +7.073 +8.882 +5.8715 +11.896 +0.004311 +0.016017 +0.0080801 +0.022467 +0.11748 +0.086135 +0.015229 +0.031512 +0.019456 +33.476 +0.0030172 +19.642 +0.013445 +0.0087755 +0.11863 +0.022371 +106.08 +38.605 +0.01515 +0.026889 +0.096896 +0.1414 +0.07446 +0.032058 +0.028253 +74.887 +2.4849e-05 +2.9093e-05 +2.5982e-05 +9.9116e-05 +3.283e-05 +1.1002e-05 +4.8244e-06 +4.3303e-06 +7.2392e-06 +1.7545e-05 +1.5748e-05 +3.6863e-05 +0.0023905 +3.5242 +6.3654 +4.3017 +0.088283 +1.8589e-05 +0.022916 +0.0067704 +0.0051019 +18.151 +23.151 +0.018656 +0.0051586 +0.022658 +0.040433 +51.461 +45.87 +18.168 +7.4751 +17.173 +2.7526 +9.7304 +0.0040515 +0.0080929 +0.034809 +0.011132 +0.021536 +14.179 +0.013404 +0.032131 +17.486 +24.019 +22.158 +15.302 +0.012288 +0.006166 +0.0084989 +31.189 +48.933 +29.389 +110.08 +0.0065736 +0.16813 +0.089147 +0.10011 +0.036126 +6.6279e-06 +0.0001296 +3.2493e-05 +2.5601e-05 +9.5479e-06 +4.6715e-05 +2.4702e-05 +8.9324e-05 +9.8013e-06 +3.5136e-06 +1.8783e-06 +1.7506e-05 +7.2354e-06 +5.5295e-06 +0.0033351 +0.001696 +2.601 +2.5906 +0.13579 +5121.2 +0.0040055 +22.014 +3.4513 +18.002 +22.652 +29.141 +0.0081796 +0.017671 +0.044969 +85.247 +85.333 +19.266 +6.8466 +12.896 +1.9131 +9.3217 +0.015539 +0.0084027 +0.034338 +0.010221 +0.012958 +0.015128 +0.0089326 +3.188e-05 +21.325 +31.627 +0.016584 +0.012581 +0.0080866 +0.0098395 +120.22 +0.012572 +40.934 +24.516 +0.016566 +0.0063942 +9.7364 +0.052723 +2.479e-05 +6.1274e-05 +1.7505e-05 +8.3339e-06 +4.0549e-06 +1.1917e-05 +2.3824e-06 +1.2139e-06 +8.4957e-06 +1.7797e-05 +3.1481e-06 +3.3224e-06 +9.7474e-06 +7.2072e-06 +2.5574e-05 +2.1377e-06 +0.0081456 +0.0041589 +0.0017169 +0.0015404 +5.6775 +0.013716 +21.408 +19.355 +7.2626 +12.958 +14.59 +0.019669 +0.0093569 +67.537 +0.026947 +28.612 +29.15 +23.952 +13.023 +19.264 +6.6976 +48.343 +48.574 +0.011226 +0.038177 +0.0061769 +0.0042907 +0.0056459 +0.0053078 +0.002873 +0.0021702 +20.389 +0.033027 +40.538 +0.0075358 +0.032975 +63.977 +56.477 +59.697 +19.291 +22.612 +0.0047043 +17.01 +3.2864e-06 +2.9714e-05 +0.00012298 +1.3757e-05 +4.3475e-05 +1.7595e-05 +2.0137e-05 +3.2129e-05 +1.3389e-06 +6.7862e-06 +7.6756e-06 +3.17e-06 +8.228e-07 +2.6471e-06 +6.5689e-06 +8.4098e-06 +2.0856e-06 +0.010899 +25.924 +0.0021645 +0.0010701 +0.011477 +82.767 +17.894 +11.883 +9.2488 +22.432 +455.71 +0.023341 +157.03 +54.792 +100.03 +30.925 +33.8 +46.941 +27.988 +48.418 +13.905 +16.025 +42.586 +28.061 +0.038485 +0.0079639 +0.0028888 +0.0048559 +0.0025837 +7.1918 +0.0030127 +0.0025532 +56.11 +56.822 +86.711 +121.97 +63.043 +181.89 +56.336 +14.195 +24.825 +2.3591e-05 +1.827e-05 +3.6279e-06 +1.4376e-05 +1.8934e-05 +1.3446e-05 +1.6527e-05 +4.125e-05 +4.6207e-05 +3.4286e-05 +2.1036e-06 +3.2588e-06 +1.2984e-05 +3.8536e-06 +1.4503e-06 +1.3669e-06 +7.1847e-06 +1.4763e-05 +1.4067e-05 +0.0090213 +19.736 +4.5969 +0.00078638 +19.502 +91.806 +14.176 +204.32 +0.13819 +0.035198 +0.060914 +0.010044 +93.882 +58.175 +79.734 +41.617 +46.287 +30.559 +21.121 +137.4 +24.363 +51.816 +41.144 +38.145 +0.026087 +0.0049476 +0.0044337 +0.0079109 +29.626 +0.0024538 +5.1497 +0.029303 +0.01609 +137.42 +82.424 +49.723 +56.558 +96.261 +42.012 +15.355 +0.00012868 +4.9845e-05 +6.9229e-06 +6.8235e-06 +2.3328e-06 +1.4641e-05 +5.5429e-05 +3.2456e-05 +1.1474e-05 +1.8441e-05 +3.7657e-06 +3.3751e-06 +4.6685e-06 +5.2535e-06 +4.3469e-05 +9.1557e-06 +5.3914e-06 +1.2411e-05 +2.6058e-05 +4.4777e-06 +17.281 +11.85 +5.6946 +0.0023733 +128.19 +0.087615 +0.046367 +422.31 +0.085321 +0.073082 +0.033003 +0.0072821 +0.011234 +52.158 +57.937 +2.5473 +2.4648 +3.3374 +0.018318 +0.050542 +3.9119 +22.776 +43.537 +21.112 +0.016503 +0.0085525 +3.948e-06 +6.3966e-06 +15.319 +9.9259 +5.0477 +0.081765 +0.029084 +194.05 +64.079 +91.081 +48.503 +0.025562 +6.356e-05 +1.7687e-05 +9.4067e-05 +5.5357e-05 +1.6547e-05 +6.2933e-06 +6.1666e-06 +1.1768e-06 +4.9334e-06 +1.0235e-05 +3.2313e-06 +1.8103e-05 +5.6532e-06 +1.7429e-05 +9.1581e-06 +1.6587e-05 +1.1756e-05 +0.00010874 +3.1652e-05 +2.2127e-05 +7.0532e-06 +3.3851e-06 +17.108 +7.1887 +0.12571 +0.12945 +187.86 +149.64 +0.028761 +0.15411 +0.079401 +0.050854 +0.026859 +0.014768 +69.093 +22.706 +14.888 +1.8629 +0.021731 +359.38 +0.032183 +57.431 +4.3137 +23.991 +29.138 +41.047 +2.1514e-06 +7.827e-07 +6.0142 +5.3468e-06 +0.0041131 +0.0051024 +0.11317 +0.090249 +0.033953 +339.19 +90.856 +113.68 +0.014517 +5.7038e-06 +1.9252e-05 +4.8657e-05 +9.0054e-05 +3.8425e-05 +3.8058e-05 +1.2796e-05 +1.6752e-05 +3.1015e-06 +6.3999e-06 +8.2118e-06 +1.279e-05 +1.472e-06 +2.2981e-05 +4.0355e-05 +6.2896e-05 +1.0493e-05 +2.2375e-05 +4.1069e-05 +1.5286e-05 +5.3713e-06 +4.3361e-05 +6.0175e-06 +31.496 +4.2566 +0.11797 +0.11576 +186.75 +226.15 +0.022104 +349.99 +0.095565 +0.019342 +86.293 +0.099452 +34.271 +26.241 +10.735 +0.018641 +107.8 +0.051198 +0.016038 +0.010418 +9.8047 +35.373 +81.194 +3.439e-06 +7.61e-07 +3.6021e-06 +5.4414e-06 +5.5327e-06 +0.19081 +0.073307 +0.090234 +0.12319 +0.086264 +0.08326 +0.01936 +0.028108 +0.021662 +5.5577e-06 +5.5177e-06 +1.469e-05 +1.1132e-05 +6.2654e-05 +3.5621e-05 +8.4066e-06 +1.2204e-05 +5.4041e-05 +2.6394e-06 +6.3307e-06 +1.806e-06 +6.9225e-06 +2.1656e-05 +3.8735e-05 +1.6511e-05 +4.4637e-06 +1.4374e-05 +4.4954e-05 +4.0793e-05 +2.2452e-06 +2.2494e-06 +1.7912e-06 +61.465 +0.019287 +65.953 +0.11392 +239.71 +0.058547 +0.016912 +0.094473 +0.1292 +0.0648 +0.22018 +0.053268 +47.372 +18.031 +0.07652 +0.028878 +0.0037104 +0.0041414 +0.021475 +0.0068606 +10.832 +0.17289 +8.7427e-06 +9.1913e-06 +1.4966e-05 +2.4793e-05 +9.7395e-06 +1.5154e-05 +0.16434 +0.13389 +0.050775 +0.098836 +0.001416 +0.0006465 +0.0067495 +0.027863 +0.060836 +2 +2.9726e-05 +8.1376e-06 +1.3631e-05 +1.5145e-05 +2.4469e-05 +7.8288e-06 +2.1849e-05 +2.5451e-05 +1.0246e-05 +4.2455e-06 +9.998e-07 +4.3855e-05 +1.858e-05 +2.3549e-05 +2.8397e-05 +3.4734e-06 +5.6939e-05 +6.5779e-06 +2.423e-05 +2.2365e-06 +3.7905e-06 +6.4475e-06 +0.015241 +0.018365 +53.752 +145.34 +0.09765 +179.5 +0.036857 +0.068721 +0.23709 +0.035839 +0.11922 +0.039732 +0.024024 +41.024 +34.244 +8.3399 +0.0050863 +0.0042337 +0.03024 +0.038122 +0.029289 +0.33807 +4.495e-05 +3.7642e-05 +4.7346e-05 +4.0705e-05 +0.0038559 +0.0024115 +0.00070979 +0.0020524 +0.00082542 +0.057913 +0.0441 +0.00070297 +0.046365 +0.014905 +0.091435 +1.1424 +0.53067 +6.5776e-06 +8.3743e-06 +1.7129e-05 +1.2881e-05 +9.8865e-06 +9.9205e-06 +3.6675e-05 +7.6694e-06 +5.0893e-06 +1.0022e-05 +2.2813e-05 +1.9427e-05 +5.4389e-06 +5.2722e-06 +5.2901e-06 +1.5553e-05 +1.0725e-05 +1.6306e-05 +3.6959e-05 +2.3806e-05 +2.3328e-05 +0.012838 +0.027195 +80.49 +138.2 +0.092667 +0.060986 +0.057622 +0.077715 +0.22057 +0.084524 +0.018652 +0.034357 +21.125 +26.39 +0.0064561 +4.8492 +0.0030278 +0.34505 +0.025444 +0.051536 +0.046631 +0.16017 +6.2995e-06 +0.019811 +0.0063856 +0.00082241 +0.0028476 +0.0037953 +0.0067873 +0.0038098 +0.0015502 +4.2198 +0.039038 +0.00093938 +4.4876 +0.026415 +0.033088 +0.48839 +0.64832 +2.7342e-06 +8.0711e-06 +2.6539e-05 +1.4223e-05 +3.6764e-06 +6.8373e-06 +8.6826e-06 +6.1436e-06 +9.274e-06 +1.1073e-05 +3.4654e-06 +5.3774e-06 +5.8785e-06 +4.813e-06 +6.8237e-06 +4.5184e-06 +5.324e-06 +1.5088e-05 +4.5824e-05 +6.4929e-06 +5.6958e-05 +0.015319 +0.047461 +85.638 +164.54 +0.042969 +0.075281 +0.022222 +0.10524 +0.11252 +0.10193 +0.030131 +0.031853 +12.124 +18.542 +14.119 +5.8715 +0.2912 +0.29657 +0.1285 +0.11 +0.036853 +0.11063 +0.15247 +0.32448 +0.0018927 +0.0011331 +0.0011707 +0.0040729 +0.010874 +0.002558 +0.0035538 +4.6754 +0.040359 +0.0079298 +3.2403 +8.0561 +0.00010501 +0.25493 +0.96141 +0.10004 +1.4624e-06 +1.2442e-05 +4.6415e-06 +1.1215e-05 +6.1612e-06 +4.5251e-06 +3.685e-07 +5.0648e-06 +8.627e-06 +2.7103e-05 +1.2599e-05 +3.3378e-06 +1.4017e-05 +6.9181e-06 +3.481e-06 +7.2204e-06 +3.2787e-06 +2.8272e-05 +3.4053e-05 +0.00015226 +0.020437 +1011 +0.095985 +208.76 +0.058035 +108.44 +0.070147 +0.02406 +0.035384 +25.3 +59.076 +0.043497 +6.901 +10.092 +8.3222 +5.1766 +0.54905 +0.53619 +0.50473 +0.13935 +0.095777 +0.2251 +0.25766 +0.80135 +0.0018239 +0.0016713 +0.002337 +0.0035998 +0.0093786 +0.0047002 +0.0045523 +0.044901 +0.050189 +5.2232 +4.0134 +6.9672 +2.5819 +3.6344e-05 +0.7011 +0.0768 +0.11655 +2.0792e-05 +1.4701e-05 +9.6241e-06 +2.2517e-05 +7.0283e-06 +1.6705e-06 +4.0251e-06 +1.7631e-06 +1.3341e-05 +4.9896e-06 +2.5569e-05 +2.3034e-05 +1.2899e-05 +6.4062e-06 +3.4764e-06 +2.8653e-06 +2.5073e-05 +3.1567e-05 +0.00010597 +0.034568 +0.059228 +0.21342 +0.12029 +0.053947 +99.211 +0.040963 +359.76 +0.066886 +37.36 +30.31 +4.6706 +0.014677 +9.8807 +15.884 +4.1051 +0.0038817 +0.55231 +0.59109 +167.46 +0.078159 +0.5226 +0.56291 +0.76378 +0.0007106 +0.0013787 +0.0034437 +0.0019076 +0.0035607 +0.0043835 +0.0056498 +0.030637 +0.037291 +12.448 +6.5647 +3.5156 +2.9073 +4.0136e-05 +1.059e-05 +0.084157 +0.093807 +0.048794 +1.0238e-06 +1.0553e-05 +4.6506e-06 +1.1898e-05 +6.2395e-06 +7.4887e-06 +3.7402e-06 +4.1439e-06 +8.5629e-06 +1.2357e-05 +4.826e-05 +5.641e-06 +2.809e-06 +8.891e-07 +7.8475e-06 +3.5253e-05 +5.9843e-05 +3.0841e-05 +0.014621 +0.0095998 +0.06748 +0.11069 +0.04417 +47.003 +0.044774 +0.020348 +0.032022 +12.684 +34.237 +5.2128 +0.011668 +7.5234 +18.276 +10.865 +0.0045414 +26.569 +0.63667 +0.049195 +0.11821 +0.61782 +0.47962 +0.44813 +2.0407e-05 +0.0011856 +0.0021926 +0.0016243 +0.0023729 +9.3971e-06 +0.006136 +0.036193 +0.02778 +13.821 +4.1436 +4.9326 +5.5823 +1.3516 +3.4962e-06 +6.3652e-06 +0.13857 +0.038644 +0.024684 +1.4137e-05 +4.5911e-05 +3.4995e-05 +2.6907e-05 +3.6218e-05 +1.9126e-05 +1.741e-05 +2.2072e-06 +1.6994e-05 +3.8305e-06 +5.0812e-06 +6.9623e-06 +6.206e-07 +2.1296e-06 +2.92e-05 +3.4715e-05 +0.00010713 +33.709 +13.025 +57.155 +0.068682 +124.01 +66.112 +0.083474 +224.65 +0.02535 +17.324 +45.034 +6.3636 +0.012576 +10.873 +0.0080544 +25.471 +0.004781 +15.551 +0.40495 +0.049062 +0.019432 +0.017038 +0.57639 +0.45976 +9.0267e-05 +8.6949e-05 +8.1293e-05 +2.5663e-05 +2e-05 +2.6418e-05 +0.0079064 +0.014185 +0.015354 +10.508 +2.8181 +2.7598 +2.2746 +1.6799 +6.0083 +4.4108e-06 +1.1056e-05 +0.024089 +0.020069 +0.0123 +0.0003858 +0.00030067 +4.0047e-05 +2.5624e-05 +6.1325e-05 +5.7434e-05 +3.5709e-05 +1.1586e-05 +3.4646e-06 +2.964e-06 +6.8849e-06 +1.4857e-06 +5.365e-07 +3.5297e-05 +5.0582e-05 +0.00011016 +33.97 +12.669 +33.387 +0.047444 +140.65 +41.432 +83.246 +259.38 +0.020123 +12.87 +18.824 +3.7936 +0.011577 +16.805 +16.142 +29.57 +0.0070706 +0.0051033 +7.3777 +7.363 +0.021043 +0.031109 +0.0080961 +0.18537 +0.14403 +5.4587e-05 +8.3071e-05 +6.988e-06 +5.1265e-06 +8.2991e-06 +0.011297 +0.03202 +0.094172 +0.22413 +5.7221 +1.9637 +1.4463 +4.3002 +1.944 +6.5746e-06 +1.132e-05 +0.01613 +0.0061142 +0.0035962 +0.0013512 +3.2989e-05 +2.049e-05 +1.7804e-05 +5.6547e-05 +4.957e-05 +3.7138e-05 +5.3374e-06 +6.3802e-06 +2.806e-05 +6.1452e-06 +3.3847e-05 +3.4291e-06 +2.3814e-05 +3.9771e-05 +2.1901e-05 +60.854 +13.052 +0.016932 +0.0052427 +0.053214 +0.11878 +70.043 +362.64 +490.38 +8.3072 +11.681 +4.317 +2.3841 +32.651 +20.4 +54.09 +31.998 +0.0098757 +7.6189 +7.9686 +15.778 +0.044693 +0.0075141 +0.19577 +348.45 +2.3214e-05 +7.412e-06 +2.4165e-06 +2.6018e-05 +0.05345 +0.011663 +76.155 +57.038 +0.16129 +0.22839 +1.3509 +1.3807 +3.171 +2.3589 +3.6369e-06 +9.6908e-06 +0.017091 +0.0053093 +0.0024879 +0.0027583 +9.919e-05 +3.2218e-05 +1.3575e-05 +7.6685e-05 +5.5023e-05 +1.5789e-05 +1.557e-05 +1.9741e-05 +2.7046e-05 +1.7342e-05 +3.2438e-05 +4.1117e-05 +5.3851e-05 +1.8219e-05 +1.2775e-05 +0.025879 +23.073 +0.0070134 +0.0083549 +0.043583 +0.010345 +0.022757 +334 +416.41 +196.68 +766.46 +2.4312 +25.28 +69.766 +20.157 +46.12 +37.66 +0.043186 +0.04219 +7.1951 +24.754 +14.863 +0.0064313 +25.102 +1.4088e-05 +1.8529e-05 +3.1038e-05 +1.0529e-05 +4.6473e-06 +0.010535 +22.878 +0.017649 +41.194 +0.090664 +0.10798 +0.028775 +1.639 +2.5853 +2.4007 +5.7809e-06 +2.6716e-05 +0.01853 +0.0035779 +0.0029912 +0.0051068 +0.00033967 +2.249e-05 +1.3473e-05 +4.8103e-05 +0.00020001 +4.0828e-05 +5.0174e-05 +2.0536e-05 +0.00012002 +5.4592e-05 +7.3546e-06 +1.3058e-05 +8.7965e-06 +1.7538e-05 +5.1666e-06 +1.1951 +171.55 +19.632 +0.0083139 +0.010029 +0.025407 +0.048144 +0.042391 +0.031372 +555.67 +360.55 +816.89 +44.85 +84.596 +32.748 +35.891 +53.517 +9.8612 +0.013376 +60.653 +0.014237 +27.387 +0.0049244 +0.0067492 +2.3922e-05 +7.2452e-06 +5.9104e-06 +0.0053378 +0.0081514 +0.0062733 +20.751 +0.01786 +23.671 +0.088198 +0.078959 +0.022926 +0.034568 +3.3845e-05 +1.69e-05 +6.5015e-05 +0.065395 +0.011503 +0.0040762 +0.0028143 +0.0018116 +5.6281e-06 +7.4211e-06 +6.3786e-06 +2.2665e-05 +0.00011135 +0.00018627 +0.00010305 +4.6698e-05 +3.2024e-05 +3.6744e-05 +3.0865e-05 +6.8377e-05 +5.4778e-06 +2.2752e-06 +9.8575e-06 +208.58 +94.364 +0.004836 +0.011648 +0.012029 +0.075804 +0.049265 +0.038725 +0.080226 +0.036469 +0.036289 +775.5 +519.53 +244.11 +49.293 +35.667 +81.144 +14.156 +0.013889 +77.349 +0.033457 +0.018502 +0.0035568 +0.006529 +0.0091223 +0.0074021 +0.0058671 +0.0089157 +0.0042217 +0.014455 +35.066 +0.038292 +0.017873 +0.12538 +0.041314 +0.032828 +0.019112 +0.012455 +0.0066652 +0.022172 +0.048579 +0.014267 +0.0022968 +0.0050586 +6.5482e-06 +9.6258e-06 +7.727e-06 +4.5136e-05 +7.232e-05 +5.0779e-05 +3.5879e-05 +0.00013405 +9.348e-05 +2.5919e-05 +3.1328e-05 +3.0467e-05 +1.1207e-05 +7.8028e-06 +9.2702e-06 +4.4516e-06 +0.39113 +35.288 +14.365 +0.0044938 +0.015371 +0.063103 +0.040918 +0.036328 +0.040672 +0.15297 +583.01 +225.81 +0.23176 +311.28 +61.653 +52.694 +64.776 +123.28 +40.99 +0.0040846 +0.0010936 +3.5188e-06 +3.7047e-06 +0.0094905 +0.007932 +0.0076547 +0.002858 +0.0097661 +0.0090744 +0.034178 +0.091511 +0.046314 +0.020347 +0.12142 +56.227 +0.0093426 +0.010297 +0.024747 +0.012224 +0.037972 +0.094923 +0.018488 +0.003448 +1.4067e-05 +1.6036e-05 +3.2147e-05 +5.5511e-05 +0.00016732 +0.0001485 +3.0166e-05 +3.5656e-05 +8.7711e-05 +0.00015999 +0.00012133 +7.1639e-06 +9.7078e-06 +6.2833e-06 +7.8319e-06 +1.1189e-05 +5.2087e-06 +0.007547 +0.032733 +0.081094 +0.004894 +0.011236 +0.013599 +0.056403 +0.042881 +97.626 +0.094308 +305.52 +133.87 +34.688 +325.95 +25.424 +100.06 +0.03352 +0.017043 +0.0090889 +0.0030856 +0.0018218 +8.446e-06 +86.754 +10.772 +0.011606 +0.015016 +0.0050736 +0.0087845 +0.0084283 +0.06862 +0.13597 +0.11563 +0.51584 +3.407e-06 +1.2671e-06 +0.0033992 +1.6328e-05 +2.3849e-05 +1.0527e-05 +1.9088e-05 +1.4316e-05 +4.9323e-06 +2.5146e-05 +1.3173e-05 +5.233e-06 +2.9288e-05 +0.00032381 +0.00017772 +0.00012188 +3.0211e-05 +4.5187e-05 +8.1733e-05 +9.5902e-05 +8.2853e-05 +1.3627e-05 +2.4409e-05 +7.3842e-06 +7.1618e-06 +9.1826e-06 +7.311e-07 +0.0056215 +0.019147 +0.086448 +0.013037 +0.0081244 +0.0094073 +0.045003 +0.02466 +0.008084 +0.043187 +164 +177.02 +36.064 +0.011254 +0.012352 +85.14 +0.039824 +22.617 +0.008179 +0.005574 +8.0217e-06 +1.8078e-05 +21.735 +5.0946 +0.009054 +0.016277 +0.0033063 +0.048843 +0.017403 +0.12347 +0.10391 +12.825 +82.339 +1.9462e-06 +1.2006e-05 +1.9701e-05 +2.7779e-05 +1.9921e-05 +3.1658e-05 +1.9006e-05 +2.0798e-05 +1.4864e-05 +3.0309e-05 +1.8967e-05 +1.2345e-05 +1.9997e-05 +1.6787e-05 +2.4989e-05 +9.9583e-06 +5.1502e-05 +2.8993e-05 +2.8413e-05 +6.0542e-05 +1.241e-05 +1.1731e-05 +1.6837e-05 +9.3039e-06 +5.6192e-06 +7.8605e-06 +1.8962e-05 +0.0055558 +0.0030342 +464.79 +56.911 +0.0089231 +0.014053 +0.048034 +0.059894 +0.01095 +0.02667 +0.037822 +164.58 +123.63 +0.014558 +0.0094822 +0.036346 +86.261 +0.0064579 +14.649 +0.0079264 +0.0054063 +8.7997 +12.472 +4.4108 +0.013429 +0.017788 +0.0041869 +0.041971 +0.019737 +0.038514 +0.16034 +4.8525 +2.3559e-05 +4.7942e-06 +5.7576e-06 +5.4416e-05 +4.8425e-05 +3.0715e-05 +7.0684e-05 +2.765e-05 +2.9715e-05 +2.0019e-05 +1.284e-05 +4.3112e-05 +1.543e-05 +1.0444e-05 +8.6e-06 +7.8884e-05 +3.1419e-05 +3.8494e-05 +5.7546e-05 +0.00055527 +6.7306e-05 +2.8949e-05 +3.2038e-06 +2.5226e-05 +1.2284e-05 +9.3856e-06 +1.2448e-05 +3.7224e-05 +0.013287 +0.0061206 +346.93 +69.785 +0.012487 +0.010949 +0.034717 +0.035827 +0.02094 +0.017735 +0.043602 +126.35 +0.037835 +0.040246 +0.034672 +0.018053 +25.096 +19.357 +23.633 +0.022911 +0.0072587 +8.7898 +11.646 +0.017989 +0.022137 +0.040722 +0.32167 +0.38479 +22.171 +9.0206 +20.736 +6.1981 +3.1024e-05 +0.00023437 +2.8557e-05 +2.806e-05 +5.2248e-05 +5.5235e-05 +0.00016657 +1.0042e-05 +2.0653e-05 +4.4536e-05 +2.626e-05 +1.2362e-05 +2.1098e-06 +9.823e-07 +6.6443e-06 +1.5849e-05 +3.5409e-06 +2.0897e-06 +3.8457e-05 +0.00015403 +0.00017864 +9.2947e-05 +1.211e-05 +1.8169e-05 +3.437e-06 +6.8512e-06 +7.26e-06 +6.3071e-06 +0.012771 +0.010222 +0.0041982 +0.014375 +0.013274 +0.0075615 +0.020233 +0.030613 +0.02387 +0.020867 +126.99 +248.31 +0.081841 +0.063315 +0.08924 +0.016511 +0.0094909 +31.859 +53.797 +141.34 +16.166 +31.337 +9.0155 +0.030397 +0.017525 +0.038458 +0.0083087 +0.33801 +18.772 +14.036 +39.141 +0.00016314 +0.00014338 +6.8098e-05 +2.3397e-05 +2.8988e-05 +3.6032e-05 +1.2572e-05 +5.5654e-05 +3.3438e-05 +8.6464e-06 +1.4357e-05 +8.8183e-06 +3.0601e-06 +1.347e-06 +3.0183e-06 +6.8391e-06 +6.299e-06 +1.6731e-05 +1.1755e-05 +1.9204e-05 +1.0179e-05 +4.8884e-05 +8.3021e-05 +1.5179e-05 +1.1309e-05 +1.5335e-05 +5.1284e-06 +1.1109e-05 +2.6902e-05 +0.013047 +0.01111 +0.0039982 +0.032416 +0.021263 +0.0080125 +0.0092203 +0.019871 +0.014607 +0.013921 +0.0061682 +621.74 +0.11015 +0.11608 +0.28283 +0.27126 +0.014474 +59.104 +95.17 +76.399 +184.41 +0.0046991 +0.027681 +0.024028 +0.042174 +0.017491 +0.012319 +14.12 +9.219 +8.1667 +7.9767e-05 +9.3031e-05 +6.527e-05 +1.8686e-05 +5.7061e-05 +1.6706e-05 +3.9984e-05 +3.5152e-05 +1.8556e-05 +2.6583e-05 +3.5237e-05 +9.1806e-06 +3.2438e-06 +3.0631e-06 +2.5176e-06 +2.6231e-06 +2.4591e-05 +0.00013939 +5.1838e-05 +3.2738e-05 +1.6568e-05 +9.7878e-06 +2.557e-05 +8.6376e-05 +1.7641e-05 +3.3889e-06 +1.4991e-06 +2.6878e-06 +8.7333e-06 +1.6469e-05 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/layer84_poro.geos b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/layer84_poro.geos new file mode 100644 index 00000000000..8e485ab5eca --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/layer84_poro.geos @@ -0,0 +1,13200 @@ +0.12171 +0.090872 +0.10906 +0.23513 +0.17799 +0.086045 +0.12965 +0.16832 +0.13882 +0.15 +0.18351 +0.24172 +0.2655 +0.20816 +0.25494 +0.28693 +0.27192 +0.34452 +0.35924 +0.19538 +0.16714 +0.27446 +0.25962 +0.31536 +0.2911 +0.30169 +0.39745 +0.31837 +0.0001 +0.029892 +0.052544 +0.14862 +0.005373 +0.049221 +0.06202 +0.060043 +0.097794 +0.054828 +0.11588 +0.093109 +0.10121 +0.14317 +0.019731 +0.11035 +0.36078 +0.32945 +0.26523 +0.22707 +0.23378 +0.23126 +0.21842 +0.25254 +0.29153 +0.1682 +0.12028 +0.19479 +0.26626 +0.27721 +0.27402 +0.20827 +0.097387 +0.080609 +0.070943 +0.066481 +0.17236 +0.079527 +0.14474 +0.10709 +0.12798 +0.14888 +0.16909 +0.23307 +0.26516 +0.21394 +0.22834 +0.2877 +0.28493 +0.3338 +0.22508 +0.17226 +0.18646 +0.29498 +0.25605 +0.31724 +0.30978 +0.29277 +0.39319 +0.36147 +0.056601 +0.078462 +0.10497 +0.056088 +0.041931 +0.017205 +0.023895 +0.092709 +0.08638 +0.094137 +0.13101 +0.088262 +0.039585 +0.065739 +0.097164 +0.10867 +0.34251 +0.36489 +0.31803 +0.19504 +0.21733 +0.24277 +0.20694 +0.2713 +0.25486 +0.26893 +0.14966 +0.18197 +0.22251 +0.39116 +0.25523 +0.22178 +0.13705 +0.1317 +0.077886 +0.13711 +0.07016 +0.1376 +0.18534 +0.19607 +0.089562 +0.17266 +0.19974 +0.22098 +0.24145 +0.2123 +0.2309 +0.27702 +0.30245 +0.2357 +0.22728 +0.17381 +0.19867 +0.29282 +0.2539 +0.31535 +0.33869 +0.29536 +0.37013 +0.33984 +0.10476 +0.062342 +0.12436 +0.070767 +0.062656 +0.014093 +0.000684 +0.05786 +0.051159 +0.027007 +0.093433 +0.06199 +0.029236 +0.10116 +0.064178 +0.085929 +0.35612 +0.38314 +0.32059 +0.28417 +0.21628 +0.23773 +0.24024 +0.30733 +0.24177 +0.27154 +0.15519 +0.19369 +0.35477 +0.38178 +0.28311 +0.25456 +0.15194 +0.19085 +0.13708 +0.13212 +0.11783 +0.19874 +0.15409 +0.078452 +0.18483 +0.22545 +0.23315 +0.23485 +0.19145 +0.18964 +0.17044 +0.25893 +0.30036 +0.27533 +0.22457 +0.1701 +0.19548 +0.26454 +0.27861 +0.32341 +0.37271 +0.29555 +0.36861 +0.34953 +0.003082 +0.057416 +0.14313 +0.09219 +0.019274 +0.0001 +0.088126 +0.15124 +0.1609 +0.057231 +0.089156 +0.12609 +0.039889 +0.017578 +0.069447 +0.085436 +0.34133 +0.37464 +0.37123 +0.24364 +0.22582 +0.25774 +0.23186 +0.29062 +0.22914 +0.26853 +0.31161 +0.21799 +0.21846 +0.23278 +0.23078 +0.25575 +0.095792 +0.17877 +0.09975 +0.12178 +0.080449 +0.16699 +0.15138 +0.057 +0.16665 +0.22629 +0.26554 +0.21734 +0.16881 +0.22358 +0.16547 +0.23009 +0.31384 +0.28686 +0.26063 +0.1803 +0.21898 +0.29953 +0.32801 +0.32413 +0.3679 +0.31122 +0.36693 +0.34663 +0.34335 +0.078008 +0.13975 +0.082159 +0.089084 +0.078919 +0.068792 +0.14734 +0.081133 +0.049118 +0.0001 +0.020162 +0.054173 +0.044744 +0.063183 +0.075704 +0.043777 +0.4 +0.37622 +0.24324 +0.21735 +0.27038 +0.2579 +0.29251 +0.27953 +0.25569 +0.29229 +0.23251 +0.26403 +0.27962 +0.23576 +0.23671 +0.052945 +0.059831 +0.090584 +0.10807 +0.16384 +0.071278 +0.054647 +0.19289 +0.14028 +0.19799 +0.22337 +0.22967 +0.1722 +0.21355 +0.19417 +0.23229 +0.25504 +0.28264 +0.2712 +0.28835 +0.2946 +0.35963 +0.3526 +0.34338 +0.36194 +0.28658 +0.32627 +0.31776 +0.3541 +0.038285 +0.11649 +0.085041 +0.050133 +0.040295 +0.086412 +0.096228 +0.012635 +0.01924 +0.036214 +0.04578 +0.069518 +0.058692 +0.17155 +0.071461 +0.050767 +0.1461 +0.30977 +0.27996 +0.23146 +0.28128 +0.24163 +0.25935 +0.30291 +0.24612 +0.35449 +0.34766 +0.27795 +0.26495 +0.22731 +0.2204 +0.16348 +0.12058 +0.13855 +0.1319 +0.1063 +0.10538 +0.30524 +0.19891 +0.19624 +0.22284 +0.24251 +0.20878 +0.25101 +0.25504 +0.20821 +0.22388 +0.22801 +0.25494 +0.21077 +0.23715 +0.29666 +0.34629 +0.31113 +0.31483 +0.30075 +0.30321 +0.29824 +0.32557 +0.31832 +0.13903 +0.12215 +0.12624 +0.056668 +0.09529 +0.10353 +0.040625 +0.0001 +0.0001 +0.063855 +0.026822 +0.10547 +0.074763 +0.024269 +0.11014 +0.28275 +0.27402 +0.31433 +0.31741 +0.24199 +0.29166 +0.25266 +0.25863 +0.34139 +0.2763 +0.29694 +0.20534 +0.26582 +0.25286 +0.19953 +0.21789 +0.13199 +0.16002 +0.16704 +0.20286 +0.14513 +0.13355 +0.26457 +0.19966 +0.18499 +0.17819 +0.22538 +0.19904 +0.2776 +0.25942 +0.18818 +0.27946 +0.23334 +0.27518 +0.23364 +0.25003 +0.29805 +0.29858 +0.20876 +0.30579 +0.28111 +0.30192 +0.32728 +0.31363 +0.27131 +0.27379 +0.12434 +0.086308 +0.10605 +0.096915 +0.052189 +0.082438 +0.069434 +0.058633 +0.040127 +0.050175 +0.010739 +0.064853 +0.057141 +0.25729 +0.31843 +0.27848 +0.31818 +0.32177 +0.25435 +0.25983 +0.26447 +0.25797 +0.24781 +0.25978 +0.27292 +0.22641 +0.29418 +0.23865 +0.20582 +0.24694 +0.10114 +0.072493 +0.10407 +0.085986 +0.1576 +0.10032 +0.22899 +0.17138 +0.21958 +0.20568 +0.22449 +0.22674 +0.2584 +0.30725 +0.28062 +0.27318 +0.26178 +0.28611 +0.23641 +0.24196 +0.25707 +0.30851 +0.30314 +0.22351 +0.26118 +0.25562 +0.33603 +0.31061 +0.26037 +0.27018 +0.32998 +0.092615 +0.03095 +0.14821 +0.098404 +0.091219 +0.051387 +0.11554 +0.05485 +0.061202 +0.022896 +0.11206 +0.085496 +0.24651 +0.29965 +0.27973 +0.28985 +0.32251 +0.24124 +0.28266 +0.28663 +0.32264 +0.22662 +0.24879 +0.26999 +0.20016 +0.28004 +0.051353 +0.06475 +0.051129 +0.077268 +0.10321 +0.094891 +0.14247 +0.07715 +0.091713 +0.2586 +0.21083 +0.20893 +0.20506 +0.25334 +0.23677 +0.27875 +0.31937 +0.27107 +0.24963 +0.25347 +0.31378 +0.22891 +0.24397 +0.25813 +0.33877 +0.31691 +0.26202 +0.25376 +0.25656 +0.23565 +0.30729 +0.27377 +0.26291 +0.35876 +0.37599 +0.1232 +0.10125 +0.10853 +0.055036 +0.06743 +0.0001 +0.0001 +0.0001 +0.11689 +0.38176 +0.27766 +0.27597 +0.2839 +0.27229 +0.28831 +0.24451 +0.25557 +0.25301 +0.27159 +0.31422 +0.25875 +0.26827 +0.18719 +0.12997 +0.10486 +0.055607 +0.086623 +0.050988 +0.03355 +0.091438 +0.11774 +0.14752 +0.058459 +0.082875 +0.25458 +0.20612 +0.21157 +0.22149 +0.23094 +0.25041 +0.27964 +0.35494 +0.2827 +0.28613 +0.24978 +0.31371 +0.22036 +0.24581 +0.24037 +0.33625 +0.29679 +0.27576 +0.24201 +0.28525 +0.2882 +0.18261 +0.15394 +0.31091 +0.3383 +0.38233 +0.307 +0.12243 +0.10574 +0.088475 +0.10179 +0.02012 +0.0001 +0.36059 +0.32522 +0.36242 +0.3246 +0.28435 +0.24127 +0.18479 +0.21868 +0.20907 +0.23048 +0.25963 +0.26723 +0.15914 +0.26013 +0.21694 +0.19017 +0.15268 +0.12317 +0.12752 +0.10664 +0.10038 +0.09246 +0.05358 +0.028643 +0.10916 +0.083478 +0.064611 +0.22876 +0.21225 +0.22466 +0.21933 +0.24653 +0.23026 +0.28195 +0.34067 +0.30323 +0.2919 +0.2145 +0.29657 +0.22729 +0.23633 +0.23987 +0.25023 +0.26245 +0.2657 +0.2219 +0.29027 +0.17143 +0.20896 +0.22317 +0.16444 +0.31673 +0.22995 +0.34492 +0.12118 +0.10424 +0.11945 +0.1186 +0.12341 +0.31523 +0.35039 +0.33898 +0.32343 +0.32703 +0.28752 +0.23538 +0.20902 +0.22277 +0.21809 +0.21919 +0.12186 +0.17627 +0.16682 +0.23237 +0.2278 +0.19148 +0.12544 +0.13526 +0.19068 +0.026729 +0.09053 +0.072143 +0.075924 +0.060107 +0.12981 +0.16962 +0.06718 +0.26961 +0.19806 +0.21015 +0.25734 +0.1828 +0.22952 +0.2627 +0.32143 +0.32739 +0.3259 +0.24451 +0.29721 +0.25656 +0.24011 +0.22462 +0.25839 +0.22417 +0.32369 +0.21098 +0.27352 +0.13975 +0.18264 +0.20963 +0.26693 +0.20359 +0.1693 +0.18486 +0.18138 +0.09348 +0.10275 +0.095506 +0.34055 +0.3404 +0.3939 +0.34822 +0.30328 +0.33898 +0.19079 +0.23882 +0.21684 +0.21756 +0.23741 +0.22923 +0.20295 +0.19623 +0.14336 +0.22629 +0.23727 +0.1803 +0.12047 +0.16425 +0.086769 +0.040901 +0.12008 +0.0001 +0.0001 +0.10011 +0.10844 +0.070487 +0.047769 +0.24915 +0.20603 +0.22717 +0.24087 +0.17546 +0.24611 +0.25608 +0.34331 +0.29222 +0.31364 +0.35721 +0.16362 +0.22609 +0.22392 +0.21895 +0.20885 +0.22575 +0.31243 +0.38147 +0.28884 +0.17785 +0.18091 +0.20945 +0.23838 +0.22424 +0.19526 +0.22269 +0.21063 +0.23496 +0.31492 +0.35501 +0.3659 +0.38803 +0.39821 +0.38089 +0.046906 +0.087867 +0.01045 +0.20741 +0.23433 +0.25157 +0.23348 +0.2337 +0.19883 +0.21721 +0.16632 +0.24027 +0.22143 +0.19702 +0.13652 +0.1405 +0.14407 +0.070742 +0.072875 +0.057284 +0.002563 +0.034627 +0.090152 +0.11135 +0.002781 +0.23255 +0.24193 +0.24926 +0.2322 +0.22813 +0.24242 +0.26371 +0.32984 +0.34064 +0.284 +0.36092 +0.18512 +0.1693 +0.21798 +0.26137 +0.22442 +0.26701 +0.31943 +0.18657 +0.21964 +0.158 +0.19531 +0.17974 +0.23491 +0.24649 +0.20421 +0.15909 +0.26204 +0.18165 +0.27391 +0.28563 +0.37273 +0.38385 +0.37771 +0.033152 +0.063656 +0.04601 +0.036277 +0.25451 +0.23652 +0.24005 +0.25526 +0.28225 +0.24927 +0.23846 +0.15244 +0.4 +0.21939 +0.25827 +0.080823 +0.13568 +0.10637 +0.071771 +0.13145 +0.02207 +0.0001 +0.019034 +0.046384 +0.028098 +0.040266 +0.21684 +0.21914 +0.24508 +0.25595 +0.24252 +0.27349 +0.28096 +0.32729 +0.29723 +0.28883 +0.34174 +0.17796 +0.18899 +0.21503 +0.26029 +0.26372 +0.24907 +0.32049 +0.22769 +0.23767 +0.18606 +0.22938 +0.21013 +0.1847 +0.23339 +0.21423 +0.18738 +0.1712 +0.2353 +0.24579 +0.25416 +0.32888 +0.39545 +0.396 +0.049738 +0.10341 +0.018827 +0.014978 +0.24039 +0.21598 +0.26316 +0.27794 +0.2622 +0.29163 +0.253 +0.25692 +0.21907 +0.23063 +0.098889 +0.051157 +0.10561 +0.078769 +0.008708 +0.06371 +0.0001 +0.0001 +0.00893 +0.0001 +0.039683 +0.067983 +0.039992 +0.088713 +0.25531 +0.24238 +0.26212 +0.255 +0.27446 +0.31787 +0.29252 +0.29429 +0.30593 +0.19511 +0.1824 +0.23275 +0.24398 +0.24564 +0.26979 +0.30368 +0.21729 +0.23075 +0.1813 +0.17471 +0.2152 +0.17647 +0.18225 +0.19538 +0.20119 +0.19847 +0.23092 +0.23964 +0.29673 +0.33106 +0.38179 +0.10608 +0.018184 +0.081992 +0.047596 +0.18371 +0.23504 +0.24237 +0.22797 +0.2866 +0.25502 +0.29063 +0.15591 +0.27259 +0.18885 +0.26391 +0.15195 +0.13953 +0.12885 +0.051643 +0.0001 +0.072308 +0.0001 +0.0001 +0.0001 +0.0001 +0.0001 +0.005985 +0.027867 +0.0001 +0.25875 +0.2488 +0.19152 +0.26092 +0.3205 +0.31746 +0.2901 +0.32293 +0.29079 +0.22342 +0.20278 +0.23645 +0.24891 +0.26711 +0.25755 +0.30588 +0.28542 +0.25626 +0.17598 +0.23697 +0.28373 +0.17629 +0.1848 +0.20618 +0.20496 +0.23153 +0.19995 +0.21735 +0.31059 +0.33479 +0.36362 +0.087186 +0.030154 +0.066402 +0.05737 +0.071445 +0.23614 +0.26911 +0.27248 +0.25073 +0.26893 +0.2708 +0.24624 +0.26545 +0.19437 +0.16048 +0.10146 +0.11496 +0.097755 +0.05851 +0.0001 +0.0001 +0.006804 +0.0001 +0.001876 +0.0001 +0.070518 +0.052865 +0.11264 +0.014908 +0.22628 +0.25258 +0.21814 +0.28655 +0.30171 +0.29955 +0.28739 +0.34138 +0.27502 +0.21804 +0.27962 +0.25264 +0.23293 +0.2863 +0.27134 +0.29662 +0.28015 +0.30121 +0.12845 +0.18911 +0.051587 +0.18027 +0.18904 +0.20402 +0.22043 +0.22234 +0.21802 +0.1991 +0.28231 +0.33337 +0.29079 +0.16553 +0.07598 +0.10403 +0.080855 +0.3167 +0.25294 +0.28562 +0.25733 +0.28685 +0.28472 +0.29522 +0.24568 +0.22926 +0.20886 +0.1354 +0.13887 +0.14414 +0.009986 +0.0001 +0.080849 +0.067292 +0.03823 +0.0001 +0.0001 +0.0001 +0.074944 +0.04885 +0.03186 +0.0001 +0.081826 +0.24257 +0.18354 +0.30815 +0.29907 +0.26455 +0.30281 +0.34312 +0.25762 +0.27711 +0.26135 +0.22398 +0.2019 +0.26909 +0.24453 +0.28954 +0.23247 +0.29752 +0.14778 +0.15893 +0.28118 +0.19646 +0.17682 +0.18827 +0.22512 +0.21929 +0.24672 +0.18398 +0.2041 +0.30816 +0.11184 +0.070765 +0.088249 +0.27621 +0.31778 +0.33638 +0.2773 +0.29546 +0.27734 +0.32535 +0.2858 +0.28232 +0.27387 +0.25118 +0.20735 +0.15208 +0.16973 +0.14876 +0.050128 +0.0001 +0.034826 +0.011028 +0.077587 +0.034525 +0.0001 +0.038644 +0.044388 +0.004961 +0.026902 +0.07576 +0.07605 +0.21108 +0.2402 +0.30414 +0.32406 +0.30355 +0.28924 +0.33452 +0.27247 +0.31086 +0.26866 +0.24419 +0.21772 +0.23283 +0.27389 +0.30248 +0.28919 +0.32221 +0.1777 +0.17083 +0.27526 +0.18827 +0.15998 +0.19018 +0.20706 +0.21665 +0.21537 +0.18636 +0.2882 +0.17078 +0.12294 +0.16989 +0.1481 +0.19458 +0.30216 +0.359 +0.31436 +0.28752 +0.31068 +0.3309 +0.27946 +0.29699 +0.3178 +0.27343 +0.1205 +0.17764 +0.1554 +0.19332 +0.054331 +0.056932 +0.061188 +0.0001 +0.16791 +0.091535 +0.08396 +0.10949 +0.070497 +0.013188 +0.027548 +0.067041 +0.14173 +0.23489 +0.24879 +0.33234 +0.32872 +0.24155 +0.29144 +0.25145 +0.29665 +0.30186 +0.30943 +0.24495 +0.24968 +0.28791 +0.30473 +0.3266 +0.31889 +0.30978 +0.13881 +0.16643 +0.19489 +0.18201 +0.14985 +0.19235 +0.20967 +0.17452 +0.20626 +0.23833 +0.16819 +0.15984 +0.15343 +0.17171 +0.2128 +0.18595 +0.1684 +0.2934 +0.32198 +0.30572 +0.29412 +0.34822 +0.26227 +0.3553 +0.31107 +0.25656 +0.14921 +0.16009 +0.10974 +0.16107 +0.16339 +0.060206 +0.0001 +0.053708 +0.13472 +0.15432 +0.12171 +0.025864 +0.032614 +0.009746 +0.19148 +0.14156 +0.12162 +0.31482 +0.25726 +0.31641 +0.35334 +0.21475 +0.22858 +0.2511 +0.2788 +0.30386 +0.29772 +0.28017 +0.24963 +0.28739 +0.31394 +0.2797 +0.30876 +0.19847 +0.1982 +0.15565 +0.17286 +0.13393 +0.1521 +0.20934 +0.23767 +0.24416 +0.15857 +0.15984 +0.12002 +0.14416 +0.094814 +0.064311 +0.17778 +0.19445 +0.21154 +0.26337 +0.23861 +0.28817 +0.28363 +0.34522 +0.28094 +0.33857 +0.31217 +0.24244 +0.19934 +0.13258 +0.14411 +0.18475 +0.050194 +0.089566 +0.052573 +0.0001 +0.1357 +0.052982 +0.0446 +0.025445 +0.041909 +0.0001 +0.19426 +0.14239 +0.1149 +0.32764 +0.29597 +0.31667 +0.23711 +0.20728 +0.20896 +0.31199 +0.25911 +0.31134 +0.32957 +0.2998 +0.2423 +0.24789 +0.31608 +0.098496 +0.22101 +0.23044 +0.19412 +0.16428 +0.14142 +0.12819 +0.28446 +0.2635 +0.29773 +0.13856 +0.10652 +0.11237 +0.033263 +0.031417 +0.045448 +0.13475 +0.17662 +0.20358 +0.23768 +0.27669 +0.2798 +0.25846 +0.26849 +0.30657 +0.28385 +0.32607 +0.32995 +0.27066 +0.27291 +0.1525 +0.17556 +0.16907 +0.04417 +0.034132 +0.0001 +0.067155 +0.098877 +0.077875 +0.046499 +0.062144 +0.055863 +0.13743 +0.16907 +0.13045 +0.12202 +0.31492 +0.25463 +0.2436 +0.16256 +0.22749 +0.22138 +0.30485 +0.25246 +0.2516 +0.32752 +0.31435 +0.28921 +0.21072 +0.19212 +0.22939 +0.26285 +0.23354 +0.19249 +0.12495 +0.092335 +0.30225 +0.30357 +0.32095 +0.093637 +0.11175 +0.16081 +0.14909 +0.091323 +0.085959 +0.04998 +0.15761 +0.20306 +0.23727 +0.27181 +0.25474 +0.31424 +0.27445 +0.25919 +0.35315 +0.33285 +0.32889 +0.32292 +0.29963 +0.27756 +0.16872 +0.17281 +0.17277 +0.16805 +0.015677 +0.0001 +0.0001 +0.09449 +0.083793 +0.0001 +0.047099 +0.035606 +0.14588 +0.18436 +0.079748 +0.3449 +0.2243 +0.25712 +0.13837 +0.15181 +0.21338 +0.24365 +0.27458 +0.27349 +0.25826 +0.27268 +0.29352 +0.21063 +0.21707 +0.19804 +0.25614 +0.26193 +0.22837 +0.1977 +0.12163 +0.30265 +0.32739 +0.3475 +0.31538 +0.29333 +0.10499 +0.026614 +0.08398 +0.022836 +0.11325 +0.19076 +0.17604 +0.17676 +0.14413 +0.26228 +0.22259 +0.14542 +0.28981 +0.24488 +0.34039 +0.34693 +0.31971 +0.31935 +0.26912 +0.24051 +0.18752 +0.1919 +0.19607 +0.20747 +0.003679 +0.0001 +0.072966 +0.071298 +0.043246 +0.03699 +0.044603 +0.081175 +0.098329 +0.18337 +0.23969 +0.22628 +0.21953 +0.17331 +0.1441 +0.13729 +0.23311 +0.26271 +0.30316 +0.29423 +0.22032 +0.15325 +0.24205 +0.18401 +0.22027 +0.24523 +0.22286 +0.24453 +0.0001 +0.087602 +0.15772 +0.24802 +0.29448 +0.35167 +0.29712 +0.25612 +0.22359 +0.020517 +0.053437 +0.047175 +0.21869 +0.14682 +0.15199 +0.13631 +0.11742 +0.22104 +0.21634 +0.25294 +0.30156 +0.25565 +0.30934 +0.33087 +0.29057 +0.31017 +0.2666 +0.26839 +0.084706 +0.21538 +0.19462 +0.23044 +0.18659 +0.034035 +0.14086 +0.071406 +0.062694 +0.0001 +0.075614 +0.067167 +0.21319 +0.21287 +0.23204 +0.20098 +0.23554 +0.15628 +0.13093 +0.16592 +0.20322 +0.27761 +0.39852 +0.20096 +0.13911 +0.14864 +0.19107 +0.16697 +0.20589 +0.21708 +0.24335 +0.067106 +0.06271 +0.073416 +0.092414 +0.13122 +0.35003 +0.32725 +0.29247 +0.22187 +0.18845 +0.2504 +0.20551 +0.22408 +0.087324 +0.19959 +0.11391 +0.10245 +0.12789 +0.092792 +0.24813 +0.22563 +0.26434 +0.25615 +0.31542 +0.32592 +0.34396 +0.14777 +0.25178 +0.21003 +0.24589 +0.24942 +0.18758 +0.25701 +0.049753 +0.012287 +0.046969 +0.068903 +0.095211 +0.04488 +0.19584 +0.15689 +0.20395 +0.1968 +0.2637 +0.25327 +0.21208 +0.19631 +0.1639 +0.16356 +0.21838 +0.38263 +0.26021 +0.23605 +0.16267 +0.16193 +0.20953 +0.14223 +0.22181 +0.22799 +0.08756 +0.090148 +0.092668 +0.13389 +0.11126 +0.34415 +0.32496 +0.27789 +0.27933 +0.20722 +0.21127 +0.24402 +0.20835 +0.20495 +0.112 +0.19857 +0.088791 +0.24074 +0.27931 +0.23514 +0.26449 +0.2571 +0.23298 +0.24244 +0.29557 +0.32074 +0.15557 +0.16841 +0.24854 +0.2085 +0.27172 +0.26557 +0.22129 +0.18874 +0.086693 +0.029134 +0.085302 +0.057845 +0.037879 +0.2067 +0.18924 +0.17729 +0.20633 +0.18462 +0.26222 +0.26171 +0.21055 +0.18924 +0.152 +0.18516 +0.21091 +0.26299 +0.23133 +0.24257 +0.18138 +0.15296 +0.19497 +0.16595 +0.28456 +0.26654 +0.0287 +0.024338 +0.11296 +0.10896 +0.16627 +0.36135 +0.31167 +0.31521 +0.24404 +0.22256 +0.2042 +0.20888 +0.18672 +0.23215 +0.056375 +0.21999 +0.25521 +0.25278 +0.2566 +0.2308 +0.28332 +0.32336 +0.24667 +0.18331 +0.14852 +0.21851 +0.19978 +0.21283 +0.26617 +0.24387 +0.24661 +0.22957 +0.19173 +0.21105 +0.053662 +0.05167 +0.02529 +0.018703 +0.13095 +0.18954 +0.20248 +0.20137 +0.17487 +0.27187 +0.28391 +0.22688 +0.21766 +0.18249 +0.1626 +0.25895 +0.25081 +0.25089 +0.25742 +0.23688 +0.21704 +0.17049 +0.22496 +0.17811 +0.24894 +0.25911 +0.24896 +0.24702 +0.10899 +0.074245 +0.12287 +0.34779 +0.29966 +0.32185 +0.23101 +0.18704 +0.18943 +0.18892 +0.19453 +0.29709 +0.043789 +0.19458 +0.26744 +0.26134 +0.2705 +0.23991 +0.2814 +0.27772 +0.21834 +0.16737 +0.14615 +0.18008 +0.19885 +0.16889 +0.29946 +0.27367 +0.28147 +0.2315 +0.19404 +0.24925 +0.034418 +0.037383 +0.017661 +0.10497 +0.14641 +0.19174 +0.20523 +0.205 +0.29813 +0.27195 +0.29039 +0.23231 +0.21304 +0.4 +0.4 +0.3448 +0.23543 +0.23591 +0.25138 +0.2411 +0.23131 +0.17975 +0.21285 +0.23904 +0.27331 +0.2381 +0.26604 +0.22419 +0.27202 +0.35568 +0.32165 +0.36139 +0.29242 +0.32134 +0.21076 +0.16337 +0.1418 +0.17958 +0.1319 +0.25865 +0.28248 +0.21803 +0.24626 +0.24116 +0.2477 +0.26382 +0.28526 +0.10659 +0.18006 +0.1613 +0.16997 +0.17571 +0.2015 +0.18143 +0.16953 +0.21144 +0.25047 +0.20308 +0.19818 +0.26661 +0.25005 +0.017859 +0.030581 +0.078818 +0.18609 +0.22136 +0.2292 +0.30079 +0.29385 +0.27554 +0.30769 +0.25162 +0.21941 +0.39643 +0.4 +0.047016 +0.24493 +0.28149 +0.28355 +0.21548 +0.26386 +0.22405 +0.23939 +0.31656 +0.24744 +0.21628 +0.25944 +0.28484 +0.28022 +0.28058 +0.31127 +0.37392 +0.27804 +0.30614 +0.21101 +0.19464 +0.11428 +0.13765 +0.098941 +0.25903 +0.24635 +0.20678 +0.22652 +0.23299 +0.26128 +0.27386 +0.25641 +0.067472 +0.23294 +0.17674 +0.14796 +0.13819 +0.15411 +0.20071 +0.20398 +0.21953 +0.21965 +0.2366 +0.22207 +0.21318 +0.20292 +0.006321 +0.030436 +0.075066 +0.18335 +0.21595 +0.38368 +0.30882 +0.28692 +0.28104 +0.2895 +0.23942 +0.3755 +0.3945 +0.4 +0.29212 +0.26311 +0.288 +0.30734 +0.21584 +0.26877 +0.25138 +0.23474 +0.24417 +0.32055 +0.22133 +0.28886 +0.3033 +0.29913 +0.2865 +0.31439 +0.35961 +0.25312 +0.24246 +0.20245 +0.14077 +0.098576 +0.10224 +0.11394 +0.21379 +0.2224 +0.26003 +0.25662 +0.20952 +0.29311 +0.29167 +0.27414 +0.13399 +0.076921 +0.2857 +0.24506 +0.17808 +0.1948 +0.21611 +0.20055 +0.2268 +0.21103 +0.22974 +0.30681 +0.24758 +0.1953 +0.091409 +0.017087 +0.007714 +0.045374 +0.02452 +0.32963 +0.33364 +0.27676 +0.27524 +0.29926 +0.2581 +0.4 +0.4 +0.14627 +0.18862 +0.2203 +0.27478 +0.2908 +0.23272 +0.24928 +0.29461 +0.19285 +0.25438 +0.26072 +0.30427 +0.31159 +0.30925 +0.3045 +0.2543 +0.23214 +0.30278 +0.22541 +0.23112 +0.18214 +0.15211 +0.096871 +0.035652 +0.093517 +0.24054 +0.2291 +0.24663 +0.24495 +0.26303 +0.27021 +0.28161 +0.33401 +0.11067 +0.23523 +0.3041 +0.27642 +0.178 +0.20215 +0.24052 +0.23652 +0.21892 +0.22486 +0.22565 +0.28066 +0.26194 +0.23967 +0.2094 +0.00248 +0.045017 +0.010783 +0.006673 +0.29719 +0.33431 +0.26478 +0.26149 +0.27595 +0.25704 +0.4 +0.10738 +0.2313 +0.21295 +0.19531 +0.2496 +0.26332 +0.25489 +0.24888 +0.28269 +0.24476 +0.23223 +0.25505 +0.3243 +0.29292 +0.32671 +0.28146 +0.27326 +0.23984 +0.24859 +0.19739 +0.22727 +0.20549 +0.029398 +0.076496 +0.023826 +0.096118 +0.2333 +0.24789 +0.2636 +0.27897 +0.23903 +0.26 +0.2831 +0.32731 +0.30832 +0.20749 +0.29727 +0.29093 +0.20627 +0.19018 +0.20584 +0.21035 +0.21035 +0.18774 +0.24703 +0.28964 +0.27332 +0.2852 +0.26675 +0.097157 +0.042568 +0.008071 +0.31861 +0.31218 +0.34114 +0.28003 +0.28214 +0.26952 +0.26869 +0.006735 +0.055219 +0.2564 +0.24955 +0.21979 +0.24283 +0.2571 +0.2514 +0.22965 +0.23312 +0.23659 +0.22953 +0.28769 +0.30884 +0.31593 +0.31773 +0.29405 +0.27928 +0.24918 +0.22334 +0.28235 +0.27652 +0.31673 +0.1092 +0.11691 +0.090965 +0.10025 +0.12593 +0.21331 +0.27342 +0.2619 +0.22712 +0.28301 +0.31932 +0.29487 +0.29475 +0.25309 +0.26206 +0.27239 +0.21437 +0.24296 +0.20515 +0.18846 +0.18714 +0.12023 +0.23288 +0.26303 +0.2702 +0.30249 +0.23947 +0.081555 +0.064549 +0.0204 +0.31974 +0.30814 +0.32797 +0.28493 +0.29444 +0.29767 +0.25602 +0.26028 +0.25636 +0.22657 +0.26055 +0.19799 +0.24261 +0.24358 +0.22769 +0.19887 +0.2135 +0.26936 +0.25891 +0.3156 +0.34067 +0.3133 +0.31121 +0.28403 +0.30229 +0.29076 +0.28667 +0.29142 +0.4 +0.32354 +0.34565 +0.19808 +0.036125 +0.058602 +0.13906 +0.11797 +0.22714 +0.24091 +0.26467 +0.31026 +0.26048 +0.27752 +0.29 +0.26834 +0.24479 +0.28058 +0.19983 +0.24435 +0.20189 +0.20159 +0.17453 +0.16337 +0.23936 +0.26812 +0.26809 +0.31368 +0.27127 +0.043633 +0.021766 +0.29731 +0.30938 +0.29331 +0.33714 +0.28315 +0.3072 +0.31396 +0.05465 +0.012599 +0.0001 +0.26746 +0.26699 +0.23434 +0.2375 +0.22386 +0.20416 +0.22664 +0.20159 +0.24848 +0.25828 +0.31669 +0.016202 +0.1136 +0.068726 +0.34758 +0.31373 +0.34034 +0.31345 +0.29678 +0.34356 +0.30169 +0.32571 +0.19062 +0.10621 +0.075608 +0.21939 +0.19553 +0.10162 +0.20334 +0.22523 +0.29596 +0.35228 +0.36534 +0.26102 +0.29072 +0.25639 +0.27388 +0.21976 +0.12003 +0.15876 +0.1807 +0.19386 +0.16754 +0.25345 +0.27147 +0.27082 +0.25633 +0.081143 +0.056464 +0.014912 +0.29201 +0.29092 +0.34848 +0.31763 +0.2428 +0.27389 +0.28645 +0.30355 +0.30286 +0.2922 +0.26875 +0.14481 +0.16102 +0.25781 +0.20401 +0.18063 +0.20947 +0.24833 +0.098071 +0.091034 +0.082563 +0.028833 +0.0989 +0.10948 +0.3558 +0.3052 +0.32302 +0.3136 +0.3061 +0.31651 +0.28824 +0.21498 +0.15643 +0.10286 +0.081703 +0.055777 +0.17335 +0.12247 +0.19412 +0.21485 +0.24904 +0.33851 +0.3672 +0.09568 +0.26369 +0.26104 +0.27237 +0.23173 +0.26496 +0.15727 +0.25466 +0.17182 +0.2623 +0.24636 +0.14435 +0.30225 +0.279 +0.076694 +0.10123 +0.028 +0.25759 +0.31831 +0.34859 +0.2871 +0.26486 +0.27389 +0.25651 +0.28638 +0.30722 +0.22999 +0.2594 +0.14305 +0.15469 +0.15022 +0.22441 +0.20522 +0.20954 +0.17693 +0.1978 +0.084024 +0.086915 +0.045192 +0.077185 +0.37448 +0.34013 +0.29198 +0.2892 +0.32692 +0.28909 +0.18446 +0.13796 +0.2168 +0.13326 +0.13763 +0.051351 +0.01927 +0.17964 +0.1236 +0.2139 +0.23372 +0.27885 +0.29561 +0.31769 +0.077102 +0.11542 +0.26656 +0.25157 +0.22387 +0.18871 +0.17841 +0.30073 +0.20672 +0.27374 +0.21642 +0.13691 +0.19986 +0.082679 +0.10829 +0.16663 +0.092455 +0.097502 +0.3167 +0.31017 +0.23583 +0.21611 +0.25562 +0.25394 +0.27847 +0.2226 +0.21625 +0.1114 +0.13119 +0.13707 +0.18777 +0.23277 +0.20522 +0.21609 +0.19716 +0.1812 +0.11431 +0.14303 +0.13791 +0.28143 +0.35371 +0.31263 +0.29535 +0.28204 +0.32106 +0.19965 +0.20201 +0.15473 +0.24655 +0.0899 +0.083905 +0.066346 +0.16877 +0.22079 +0.17325 +0.20788 +0.27316 +0.26226 +0.30695 +0.28266 +0.26662 +0.083303 +0.091174 +0.11396 +0.23911 +0.20872 +0.1797 +0.22831 +0.21094 +0.2431 +0.2018 +0.16581 +0.22929 +0.2105 +0.031466 +0.12363 +0.092589 +0.089922 +0.084199 +0.3053 +0.24628 +0.24657 +0.24077 +0.2214 +0.25924 +0.32168 +0.18366 +0.085103 +0.1377 +0.12929 +0.22355 +0.17751 +0.20489 +0.21126 +0.19542 +0.16451 +0.054968 +0.086922 +0.10119 +0.28702 +0.27804 +0.30247 +0.3346 +0.27361 +0.2698 +0.19559 +0.17044 +0.16835 +0.13687 +0.11449 +0.086673 +0.069108 +0.002944 +0.068049 +0.007845 +0.014521 +0.23533 +0.31136 +0.32044 +0.31252 +0.056843 +0.10284 +0.12088 +0.12196 +0.1422 +0.22515 +0.21169 +0.23317 +0.24449 +0.20607 +0.18929 +0.20833 +0.21431 +0.20771 +0.18218 +0.014586 +0.13555 +0.052188 +0.082258 +0.040066 +0.2567 +0.24183 +0.2178 +0.19545 +0.23428 +0.35245 +0.083664 +0.10035 +0.18412 +0.14143 +0.22079 +0.23889 +0.098177 +0.21517 +0.20826 +0.17328 +0.17315 +0.14596 +0.15469 +0.27524 +0.29116 +0.32753 +0.32388 +0.27158 +0.2671 +0.20483 +0.18801 +0.20596 +0.13826 +0.10484 +0.053727 +0.063851 +0.016286 +0.065766 +0.031666 +0.26633 +0.22208 +0.31261 +0.29305 +0.31183 +0.094262 +0.11605 +0.098205 +0.069263 +0.16164 +0.2519 +0.22935 +0.26344 +0.21489 +0.24802 +0.28017 +0.19843 +0.18363 +0.2141 +0.18773 +0.064623 +0.12902 +0.078184 +0.14031 +0.0696 +0.25476 +0.24859 +0.23035 +0.19212 +0.25487 +0.12276 +0.087565 +0.098042 +0.18444 +0.24767 +0.24053 +0.22514 +0.22817 +0.2116 +0.18296 +0.19157 +0.1718 +0.13336 +0.26507 +0.29231 +0.31178 +0.33357 +0.31769 +0.24421 +0.27386 +0.25738 +0.16264 +0.19734 +0.16262 +0.19549 +0.049407 +0.079647 +0.087119 +0.070552 +0.28275 +0.26086 +0.26084 +0.31457 +0.28909 +0.15123 +0.099557 +0.1194 +0.12986 +0.092013 +0.15762 +0.15558 +0.20126 +0.27023 +0.23065 +0.24185 +0.25588 +0.18441 +0.19626 +0.24066 +0.22324 +0.22888 +0.15123 +0.075641 +0.064029 +0.28492 +0.22978 +0.22799 +0.20054 +0.20308 +0.15561 +0.13939 +0.061793 +0.10863 +0.14261 +0.088394 +0.2338 +0.21479 +0.23256 +0.27003 +0.13673 +0.1689 +0.17307 +0.14233 +0.21185 +0.32149 +0.313 +0.31716 +0.30112 +0.21186 +0.27956 +0.30279 +0.085802 +0.10403 +0.094659 +0.23874 +0.23569 +0.30412 +0.073385 +0.26287 +0.28129 +0.29543 +0.28426 +0.32248 +0.17459 +0.12214 +0.1187 +0.14666 +0.12738 +0.1105 +0.12169 +0.23954 +0.20202 +0.27131 +0.22027 +0.25172 +0.25131 +0.18255 +0.17622 +0.25068 +0.25638 +0.23403 +0.095813 +0.13217 +0.064883 +0.29257 +0.23388 +0.20785 +0.21051 +0.20017 +0.18939 +0.16653 +0.087574 +0.10292 +0.12878 +0.26211 +0.083898 +0.22448 +0.25798 +0.27864 +0.20063 +0.21384 +0.15814 +0.14121 +0.18897 +0.17827 +0.29653 +0.30635 +0.279 +0.23827 +0.27893 +0.046515 +0.032458 +0.065623 +0.054977 +0.065821 +0.047548 +0.21878 +0.25976 +0.26368 +0.27696 +0.29676 +0.30315 +0.18983 +0.15763 +0.14336 +0.15299 +0.14599 +0.096271 +0.11912 +0.11959 +0.23745 +0.22432 +0.27318 +0.23952 +0.29809 +0.19592 +0.14618 +0.16354 +0.23049 +0.21174 +0.1864 +0.053284 +0.12552 +0.046438 +0.031388 +0.22076 +0.24572 +0.17056 +0.20181 +0.26517 +0.1773 +0.1013 +0.12713 +0.11771 +0.25963 +0.14345 +0.21099 +0.23197 +0.29583 +0.23913 +0.218 +0.15451 +0.16556 +0.17206 +0.17204 +0.19764 +0.30542 +0.31656 +0.042994 +0.000147 +0.077125 +0.084085 +0.095198 +0.12019 +0.2119 +0.28252 +0.27114 +0.24691 +0.26319 +0.24483 +0.29102 +0.13386 +0.23801 +0.17861 +0.13598 +0.10609 +0.16506 +0.19449 +0.16101 +0.1784 +0.23802 +0.22863 +0.30385 +0.26975 +0.32831 +0.14902 +0.12698 +0.15275 +0.21942 +0.18208 +0.1911 +0.13022 +0.1897 +0.14409 +0.10175 +0.22055 +0.26875 +0.13488 +0.16164 +0.2525 +0.20101 +0.096487 +0.13019 +0.14032 +0.14708 +0.16769 +0.19181 +0.30358 +0.33797 +0.2102 +0.21273 +0.15288 +0.15518 +0.14013 +0.16392 +0.19431 +0.26858 +0.31611 +0.046188 +0.077057 +0.003404 +0.10452 +0.071477 +0.083193 +0.2151 +0.2728 +0.28384 +0.25278 +0.27487 +0.24482 +0.088406 +0.11973 +0.16336 +0.15093 +0.12935 +0.20052 +0.22876 +0.15297 +0.12891 +0.21335 +0.24727 +0.24616 +0.2957 +0.16886 +0.17747 +0.20554 +0.2296 +0.20084 +0.23274 +0.18512 +0.20799 +0.12611 +0.20576 +0.064093 +0.19002 +0.095039 +0.2346 +0.17016 +0.1592 +0.21208 +0.20752 +0.13111 +0.15532 +0.12011 +0.098487 +0.20601 +0.18895 +0.29634 +0.34363 +0.23533 +0.21113 +0.12205 +0.14691 +0.14626 +0.17167 +0.22851 +0.27012 +0.074933 +0.08329 +0.10239 +0.072974 +0.05905 +0.057822 +0.053536 +0.23904 +0.24827 +0.25313 +0.23236 +0.28224 +0.25388 +0.10178 +0.1295 +0.17638 +0.1244 +0.26935 +0.21239 +0.18475 +0.1296 +0.16571 +0.21514 +0.29508 +0.22163 +0.1632 +0.17889 +0.17143 +0.21546 +0.21496 +0.19425 +0.20474 +0.20564 +0.17379 +0.093217 +0.094519 +0.09192 +0.097936 +0.091912 +0.1261 +0.26389 +0.25463 +0.22769 +0.18602 +0.10681 +0.1669 +0.12764 +0.16117 +0.16635 +0.24092 +0.28877 +0.30797 +0.2388 +0.22717 +0.15756 +0.13185 +0.14286 +0.16151 +0.25505 +0.03557 +0.046495 +0.041428 +0.096275 +0.059219 +0.096895 +0.083487 +0.06353 +0.23659 +0.24344 +0.26442 +0.26065 +0.28853 +0.29482 +0.10383 +0.080952 +0.15687 +0.23894 +0.25151 +0.17236 +0.2134 +0.11349 +0.20341 +0.21174 +0.17851 +0.2246 +0.17763 +0.16385 +0.18488 +0.18491 +0.205 +0.18103 +0.20671 +0.21158 +0.14698 +0.072233 +0.11765 +0.12075 +0.16967 +0.11098 +0.10723 +0.12845 +0.26301 +0.24242 +0.1755 +0.092289 +0.16012 +0.14319 +0.21861 +0.29519 +0.29142 +0.28745 +0.27127 +0.22712 +0.19577 +0.18603 +0.13579 +0.15429 +0.16119 +0.25314 +0.030203 +0.0001 +0.0001 +0.0001 +0.052339 +0.0001 +0.018935 +0.036917 +0.25994 +0.22804 +0.25252 +0.28632 +0.28402 +0.32636 +0.29841 +0.32055 +0.2883 +0.22363 +0.27891 +0.22788 +0.23199 +0.21374 +0.24341 +0.26612 +0.22529 +0.25968 +0.17878 +0.12166 +0.15129 +0.15755 +0.20362 +0.19013 +0.24777 +0.21377 +0.15088 +0.10916 +0.070344 +0.15543 +0.11059 +0.06317 +0.016983 +0.054128 +0.16187 +0.24075 +0.16873 +0.099508 +0.176 +0.15558 +0.19586 +0.26644 +0.26509 +0.26515 +0.24192 +0.25092 +0.19445 +0.16615 +0.1443 +0.15097 +0.4 +0.050793 +0.0001 +0.0001 +0.037539 +0.0001 +0.023289 +0.013406 +0.0001 +0.064131 +0.24743 +0.22155 +0.25336 +0.31358 +0.31793 +0.32508 +0.0001 +0.30118 +0.21063 +0.20602 +0.20475 +0.22788 +0.22989 +0.2422 +0.27088 +0.28137 +0.25716 +0.24158 +0.18896 +0.11899 +0.17409 +0.16944 +0.17275 +0.25952 +0.25722 +0.22296 +0.23496 +0.046716 +0.080206 +0.08876 +0.093027 +0.037702 +0.084354 +0.052063 +0.095014 +0.20143 +0.19461 +0.14241 +0.14912 +0.14017 +0.20355 +0.26482 +0.23254 +0.255 +0.26498 +0.23289 +0.19567 +0.18972 +0.14169 +0.15979 +0.24246 +0.061739 +0.0001 +0.0001 +0.012745 +0.0001 +0.079492 +0.03652 +0.019247 +0.07367 +0.037929 +0.2184 +0.23286 +0.27831 +0.32664 +0.35599 +0.19076 +0.20814 +0.191 +0.24925 +0.24446 +0.25374 +0.27011 +0.24379 +0.24946 +0.22216 +0.23014 +0.21152 +0.17958 +0.24748 +0.2058 +0.26758 +0.23783 +0.2333 +0.22693 +0.22484 +0.24167 +0.037132 +0.05674 +0.10511 +0.028577 +0.076518 +0.080267 +0.079771 +0.11799 +0.12394 +0.16427 +0.1854 +0.11265 +0.18283 +0.21935 +0.23281 +0.18915 +0.21811 +0.26164 +0.22104 +0.20953 +0.18265 +0.14932 +0.18862 +0.3689 +0.022118 +0.046295 +0.062074 +0.032405 +0.041157 +0.027545 +0.0001 +0.0001 +0.014017 +0.044028 +0.22839 +0.23023 +0.22977 +0.28 +0.22612 +0.1596 +0.16995 +0.17095 +0.216 +0.26373 +0.25878 +0.23948 +0.22665 +0.23087 +0.20441 +0.32306 +0.12777 +0.1149 +0.25606 +0.25804 +0.2395 +0.27683 +0.2388 +0.24187 +0.22113 +0.24427 +0.020691 +0.040923 +0.10343 +0.031327 +0.054625 +0.085436 +0.097843 +0.10204 +0.049736 +0.11952 +0.19425 +0.15325 +0.12893 +0.21194 +0.19078 +0.19394 +0.21213 +0.25362 +0.18778 +0.19634 +0.17239 +0.15466 +0.37613 +0.24195 +0.0001 +0.0001 +0.055294 +0.071467 +0.056592 +0.09991 +0.02871 +0.0001 +0.052694 +0.080763 +0.15206 +0.27362 +0.23136 +0.23279 +0.23179 +0.14891 +0.18004 +0.186 +0.21812 +0.2278 +0.24863 +0.2724 +0.30697 +0.16974 +0.23966 +0.24238 +0.27306 +0.22909 +0.2516 +0.27875 +0.24464 +0.26187 +0.22552 +0.22814 +0.18788 +0.13856 +0.038469 +0.002273 +0.035782 +0.018399 +0.018585 +0.0001 +0.0001 +0.049791 +0.015055 +0.20656 +0.16892 +0.11895 +0.15243 +0.25465 +0.23327 +0.1796 +0.21116 +0.26658 +0.18102 +0.17008 +0.13899 +0.17757 +0.4 +0.22628 +0.023349 +0.0001 +0.094172 +0.028391 +0.059726 +0.068894 +0.093381 +0.10515 +0.090646 +0.13027 +0.090007 +0.20928 +0.23751 +0.21994 +0.22845 +0.17561 +0.17254 +0.21207 +0.23516 +0.31735 +0.28455 +0.2321 +0.31494 +0.32972 +0.29779 +0.23841 +0.2253 +0.18837 +0.16151 +0.13898 +0.26537 +0.034312 +0.0001 +0.0001 +0.13423 +0.097243 +0.002441 +0.018456 +0.055661 +0.076011 +0.051104 +0.07243 +0.055122 +0.009525 +0.0001 +0.0001 +0.16246 +0.16637 +0.17144 +0.18243 +0.27797 +0.16942 +0.21604 +0.23584 +0.17073 +0.15382 +0.14803 +0.22002 +0.17974 +0.19438 +0.064574 +0.072249 +0.046417 +0.082649 +0.046515 +0.098781 +0.1706 +0.14814 +0.015741 +0.086318 +0.13511 +0.19703 +0.25173 +0.26932 +0.22631 +0.17698 +0.20235 +0.226 +0.24129 +0.2981 +0.26168 +0.23722 +0.30216 +0.32215 +0.30608 +0.23157 +0.25102 +0.18502 +0.1613 +0.18307 +0.1628 +0.06706 +0.054463 +0.001054 +0.094866 +0.10683 +0.053044 +0.061425 +0.054795 +0.043356 +0.18374 +0.18641 +0.17502 +0.22577 +0.28127 +0.1839 +0.15347 +0.15922 +0.1841 +0.16709 +0.2368 +0.14039 +0.20187 +0.21868 +0.17494 +0.12098 +0.15094 +0.21316 +0.18335 +0.045068 +0.064763 +0.07554 +0.13977 +0.11553 +0.11338 +0.11597 +0.071255 +0.024764 +0.044824 +0.19585 +0.16463 +0.247 +0.22862 +0.25817 +0.2245 +0.21622 +0.20251 +0.24216 +0.20247 +0.22412 +0.27356 +0.28787 +0.33689 +0.30879 +0.32545 +0.30817 +0.22742 +0.27015 +0.14347 +0.17558 +0.17963 +0.29229 +0.2756 +0.061025 +0.073354 +0.10966 +0.046027 +0.048752 +0.071142 +0.13692 +0.20135 +0.19967 +0.18561 +0.37023 +0.34025 +0.27305 +0.16734 +0.13728 +0.16403 +0.15646 +0.1705 +0.1316 +0.18052 +0.19719 +0.15509 +0.10659 +0.18327 +0.19173 +0.21168 +0.22705 +0.09091 +0.060255 +0.094316 +0.063134 +0.052686 +0.064015 +0.13123 +0.12196 +0.045882 +0.17396 +0.15262 +0.19519 +0.22385 +0.24342 +0.19457 +0.19809 +0.20262 +0.18702 +0.18431 +0.19998 +0.22803 +0.29558 +0.31222 +0.29588 +0.2988 +0.009865 +0.25616 +0.31589 +0.23475 +0.22536 +0.2024 +0.27138 +0.29094 +0.28662 +0.10042 +0.15309 +0.030233 +0.17627 +0.091669 +0.14821 +0.1656 +0.1939 +0.070953 +0.38905 +0.31039 +0.26322 +0.15179 +0.09915 +0.14261 +0.12145 +0.15094 +0.13159 +0.17393 +0.18959 +0.15126 +0.11785 +0.16487 +0.15188 +0.21893 +0.17532 +0.18637 +0.073998 +0.036434 +0.0921 +0.043843 +0.11805 +0.17503 +0.13609 +0.1255 +0.17022 +0.18945 +0.22021 +0.21423 +0.26198 +0.16251 +0.2165 +0.16468 +0.1937 +0.22932 +0.21713 +0.21172 +0.23769 +0.32217 +0.29405 +0.29564 +0.18622 +0.31206 +0.32443 +0.27198 +0.27749 +0.23396 +0.30439 +0.28482 +0.27926 +0.2454 +0.089182 +0.1609 +0.18716 +0.13457 +0.17468 +0.13789 +0.081937 +0.10106 +0.38053 +0.34358 +0.27914 +0.16434 +0.13938 +0.15618 +0.12428 +0.15232 +0.12485 +0.18895 +0.29171 +0.12882 +0.14556 +0.15879 +0.14242 +0.23513 +0.15862 +0.18322 +0.19237 +0.21895 +0.11215 +0.15442 +0.099487 +0.1472 +0.12117 +0.12717 +0.16074 +0.14495 +0.18479 +0.2321 +0.31448 +0.31873 +0.31561 +0.29806 +0.23007 +0.23415 +0.24007 +0.2518 +0.23758 +0.33456 +0.27139 +0.25773 +0.20924 +0.32742 +0.26808 +0.22302 +0.23066 +0.22839 +0.2899 +0.29475 +0.30492 +0.20847 +0.030657 +0.15546 +0.15197 +0.14294 +0.17636 +0.072258 +0.081037 +0.080905 +0.39712 +0.30778 +0.30297 +0.19065 +0.16304 +0.17262 +0.13996 +0.12571 +0.10681 +0.20027 +0.29571 +0.31025 +0.14604 +0.13557 +0.17339 +0.22801 +0.17382 +0.21378 +0.22666 +0.21008 +0.11438 +0.13288 +0.052756 +0.15946 +0.10753 +0.10281 +0.052294 +0.15761 +0.18907 +0.22668 +0.31203 +0.28683 +0.28338 +0.29243 +0.22975 +0.24685 +0.24288 +0.20359 +0.256 +0.23178 +0.29659 +0.25034 +0.21068 +0.28045 +0.24369 +0.21394 +0.22513 +0.26066 +0.25512 +0.28332 +0.3019 +0.22115 +0.043952 +0.16544 +0.19506 +0.18618 +0.20234 +0.16001 +0.093341 +0.007629 +0.2793 +0.29235 +0.3143 +0.18097 +0.1754 +0.13513 +0.15078 +0.12159 +0.074643 +0.31145 +0.2886 +0.14109 +0.14233 +0.1502 +0.16024 +0.19819 +0.17782 +0.19938 +0.25744 +0.20983 +0.13289 +0.1072 +0.12121 +0.1539 +0.11984 +0.14847 +0.27421 +0.19827 +0.17622 +0.24152 +0.2767 +0.29651 +0.18312 +0.23527 +0.21856 +0.26329 +0.23109 +0.20057 +0.25019 +0.088933 +0.28738 +0.23696 +0.24031 +0.26398 +0.007741 +0.24176 +0.23416 +0.2462 +0.24861 +0.2866 +0.29099 +0.22812 +0.085521 +0.050847 +0.21917 +0.18873 +0.21048 +0.19647 +0.18593 +0.038136 +0.3726 +0.36938 +0.25608 +0.28713 +0.32768 +0.25537 +0.23537 +0.31818 +0.3121 +0.21235 +0.21921 +0.13309 +0.12404 +0.10396 +0.19754 +0.20377 +0.12188 +0.16621 +0.24864 +0.23903 +0.14564 +0.19606 +0.23952 +0.13518 +0.093199 +0.091574 +0.1238 +0.18863 +0.1918 +0.21494 +0.28692 +0.22732 +0.19396 +0.2092 +0.23271 +0.25926 +0.23777 +0.24209 +0.15309 +0.15761 +0.12113 +0.2312 +0.2858 +0.27541 +0.27634 +0.26044 +0.2154 +0.25829 +0.27798 +0.32146 +0.32508 +0.065884 +0.12481 +0.037967 +0.040457 +0.15953 +0.22821 +0.24318 +0.24843 +0.21575 +0.041564 +0.36324 +0.26214 +0.23948 +0.29762 +0.30247 +0.21153 +0.28107 +0.27336 +0.21996 +0.20447 +0.15185 +0.14133 +0.22202 +0.19464 +0.20818 +0.13561 +0.11566 +0.11088 +0.19984 +0.19237 +0.21403 +0.20169 +0.20637 +0.14607 +0.13488 +0.20691 +0.20814 +0.19764 +0.19441 +0.29795 +0.22622 +0.16682 +0.21658 +0.19479 +0.22967 +0.22348 +0.20647 +0.13702 +0.041555 +0.11485 +0.25998 +0.27482 +0.33787 +0.27449 +0.22518 +0.19435 +0.27554 +0.23293 +0.0001 +0.020896 +0.021656 +0.064173 +0.1197 +0.11515 +0.069743 +0.041183 +0.23858 +0.22857 +0.18766 +0.27462 +0.33123 +0.29998 +0.23758 +0.29084 +0.31162 +0.20977 +0.27992 +0.2935 +0.238 +0.21435 +0.17886 +0.25517 +0.26808 +0.19498 +0.23065 +0.14566 +0.090091 +0.12138 +0.075661 +0.19687 +0.20534 +0.22131 +0.22199 +0.13719 +0.087379 +0.21232 +0.19285 +0.21189 +0.25591 +0.29389 +0.23429 +0.14449 +0.21205 +0.19462 +0.18643 +0.20349 +0.059804 +0.1182 +0.10017 +0.043297 +0.012837 +0.3144 +0.33376 +0.25737 +0.30416 +0.23261 +0.24789 +0.15652 +0.04133 +0.075733 +0.077413 +0.061243 +0.13242 +0.11555 +0.089051 +0.091326 +0.11163 +0.25585 +0.26614 +0.23079 +0.29175 +0.30272 +0.23589 +0.3044 +0.37882 +0.28796 +0.28142 +0.31168 +0.28465 +0.28973 +0.19195 +0.26278 +0.29188 +0.31226 +0.2953 +0.15063 +0.081865 +0.096015 +0.083677 +0.136 +0.16088 +0.22127 +0.22392 +0.17077 +0.14139 +0.16193 +0.17398 +0.19512 +0.25492 +0.30857 +0.19822 +0.14022 +0.19477 +0.21208 +0.19593 +0.1788 +0.18491 +0.098731 +0.053509 +0.21426 +0.26606 +0.29056 +0.34789 +0.28144 +0.30661 +0.054223 +0.041927 +0.083467 +0.086084 +0.095373 +0.05399 +0.10052 +0.098013 +0.19404 +0.12399 +0.065252 +0.28532 +0.24814 +0.26005 +0.24591 +0.33244 +0.27282 +0.2787 +0.30465 +0.37994 +0.30454 +0.29916 +0.27075 +0.1859 +0.22392 +0.22237 +0.26837 +0.30473 +0.086714 +0.058816 +0.056096 +0.08184 +0.13247 +0.080142 +0.11922 +0.13847 +0.14855 +0.24511 +0.009489 +0.15161 +0.1438 +0.13035 +0.20382 +0.26089 +0.10904 +0.21271 +0.15617 +0.18736 +0.24419 +0.20793 +0.25187 +0.16894 +0.31736 +0.21411 +0.22865 +0.2617 +0.27716 +0.33125 +0.30923 +0.051152 +0.016561 +0.048735 +0.073555 +0.082155 +0.080772 +0.095044 +0.016215 +0.095804 +0.12721 +0.12552 +0.22983 +0.27845 +0.22278 +0.21924 +0.24216 +0.20897 +0.20683 +0.3219 +0.31162 +0.33391 +0.30378 +0.33328 +0.22703 +0.17529 +0.23483 +0.24775 +0.27938 +0.017748 +0.033741 +0.048162 +0.040969 +0.26284 +0.15341 +0.076914 +0.10602 +0.13032 +0.15849 +0.020042 +0.16095 +0.16747 +0.17459 +0.12277 +0.20247 +0.23588 +0.21237 +0.23416 +0.18433 +0.20199 +0.22734 +0.19549 +0.34145 +0.272 +0.29744 +0.29954 +0.24438 +0.24664 +0.26188 +0.3269 +0.32017 +0.007434 +0.0001 +0.075635 +0.15113 +0.084627 +0.15033 +0.1688 +0.10676 +0.075388 +0.12158 +0.14129 +0.22148 +0.29745 +0.24485 +0.25133 +0.17987 +0.23745 +0.22705 +0.3265 +0.24055 +0.28704 +0.29323 +0.26879 +0.29524 +0.19448 +0.24554 +0.27237 +0.29903 +0.077754 +0.053364 +0.3006 +0.34235 +0.30769 +0.35461 +0.08085 +0.13779 +0.11176 +0.17804 +0.18806 +0.201 +0.19296 +0.15195 +0.17349 +0.23649 +0.23972 +0.21642 +0.2387 +0.21241 +0.20845 +0.21566 +0.27613 +0.30116 +0.29475 +0.26753 +0.29668 +0.21549 +0.28205 +0.29057 +0.0001 +0.052913 +0.030961 +0.035848 +0.11947 +0.15078 +0.11237 +0.11741 +0.11692 +0.041212 +0.079873 +0.12501 +0.10574 +0.18333 +0.2081 +0.21517 +0.22047 +0.18324 +0.21847 +0.23239 +0.23575 +0.25817 +0.30013 +0.28158 +0.25428 +0.30728 +0.21241 +0.21587 +0.19939 +0.26517 +0.000421 +0.33615 +0.32325 +0.34447 +0.32582 +0.32884 +0.35359 +0.17373 +0.11535 +0.15477 +0.16142 +0.22541 +0.17969 +0.2779 +0.2264 +0.26928 +0.23363 +0.17734 +0.22488 +0.17046 +0.18715 +0.21064 +0.085055 +0.34259 +0.34143 +0.29174 +0.25075 +0.25914 +0.27274 +0.11984 +0.043478 +0.0001 +0.0001 +0.071221 +0.087536 +0.095366 +0.16663 +0.1063 +0.021308 +0.050717 +0.080306 +0.065244 +0.16928 +0.17461 +0.21399 +0.22509 +0.2446 +0.31567 +0.22606 +0.24127 +0.27865 +0.2691 +0.30199 +0.24443 +0.2824 +0.32209 +0.27704 +0.21359 +0.20837 +0.21591 +0.27846 +0.33793 +0.30935 +0.33807 +0.09629 +0.0001 +0.080814 +0.1782 +0.14044 +0.13893 +0.18793 +0.21497 +0.18542 +0.2849 +0.23708 +0.26503 +0.23766 +0.14032 +0.21835 +0.20729 +0.17016 +0.19582 +0.13302 +0.29097 +0.2879 +0.24972 +0.25975 +0.25747 +0.31326 +0.29512 +0.11375 +0.21085 +0.097998 +0.09677 +0.11558 +0.1662 +0.12798 +0.051203 +0.01552 +0.037862 +0.10644 +0.27396 +0.24307 +0.18446 +0.21878 +0.23792 +0.23669 +0.3082 +0.25767 +0.27406 +0.24931 +0.29186 +0.29787 +0.23309 +0.28716 +0.27875 +0.29812 +0.18999 +0.24685 +0.22418 +0.26891 +0.25698 +0.092555 +0.11586 +0.09607 +0.10489 +0.13335 +0.21554 +0.13913 +0.14019 +0.17615 +0.19537 +0.18541 +0.27694 +0.26119 +0.27252 +0.26058 +0.18896 +0.2159 +0.22425 +0.18899 +0.22235 +0.21973 +0.25438 +0.27331 +0.21958 +0.21885 +0.13739 +0.29886 +0.3324 +0.35994 +0.4 +0.21807 +0.15314 +0.085793 +0.12964 +0.11813 +0.020272 +0.037482 +0.0001 +0.28632 +0.29608 +0.27801 +0.18579 +0.21629 +0.26059 +0.27189 +0.30221 +0.27768 +0.30341 +0.26103 +0.27071 +0.28035 +0.22334 +0.28891 +0.29665 +0.17224 +0.19033 +0.22986 +0.19674 +0.2468 +0.24883 +0.10093 +0.11064 +0.099139 +0.10906 +0.22431 +0.19926 +0.15822 +0.15768 +0.18161 +0.1994 +0.19395 +0.24322 +0.23986 +0.22829 +0.28031 +0.204 +0.21582 +0.029338 +0.26704 +0.23316 +0.215 +0.2226 +0.28609 +0.24964 +0.25242 +0.13154 +0.16223 +0.088726 +0.39906 +0.4 +0.4 +0.4 +0.12289 +0.057848 +0.042108 +0.026917 +0.029236 +0.0001 +0.25926 +0.3031 +0.26042 +0.17844 +0.13581 +0.15877 +0.26415 +0.34119 +0.28339 +0.31916 +0.26619 +0.28911 +0.26337 +0.19818 +0.16835 +0.16466 +0.17257 +0.24824 +0.26781 +0.27003 +0.26382 +0.27669 +0.2207 +0.29766 +0.20943 +0.23055 +0.27577 +0.20353 +0.18847 +0.2055 +0.1964 +0.18586 +0.24336 +0.23112 +0.21085 +0.21831 +0.28652 +0.20726 +0.0001 +0.022684 +0.24019 +0.18752 +0.19343 +0.17895 +0.27894 +0.21366 +0.22558 +0.13157 +0.15154 +0.076051 +0.03056 +0.26749 +0.37278 +0.4 +0.4 +0.17162 +0.0001 +0.0001 +0.012463 +0.0001 +0.28168 +0.25235 +0.25085 +0.18551 +0.2153 +0.15826 +0.21361 +0.35258 +0.30407 +0.29776 +0.26872 +0.30352 +0.32443 +0.19262 +0.08168 +0.069459 +0.25781 +0.23352 +0.2851 +0.29703 +0.25461 +0.24572 +0.24432 +0.29931 +0.23206 +0.24677 +0.27821 +0.22057 +0.16693 +0.19129 +0.19529 +0.29187 +0.25976 +0.25707 +0.24527 +0.15384 +0.065618 +0.11527 +0.017792 +0.043114 +0.21632 +0.17228 +0.22365 +0.23121 +0.297 +0.22112 +0.22282 +0.13321 +0.13683 +0.29672 +0.068805 +0.053545 +0.29009 +0.34338 +0.4 +0.4 +0.34808 +0.1611 +0.048655 +0.072108 +0.28396 +0.26645 +0.22262 +0.17119 +0.15663 +0.14858 +0.1956 +0.18355 +0.30159 +0.30184 +0.27139 +0.28933 +0.36104 +0.32079 +0.063837 +0.057729 +0.027434 +0.0001 +0.2848 +0.29209 +0.23009 +0.23493 +0.24881 +0.27166 +0.27125 +0.27319 +0.26219 +0.22887 +0.098091 +0.089577 +0.23751 +0.26554 +0.26205 +0.26196 +0.2504 +0.11215 +0.095811 +0.039712 +0.051098 +0.22324 +0.22 +0.20083 +0.24046 +0.20635 +0.27453 +0.19531 +0.18551 +0.13487 +0.25812 +0.05386 +0.0001 +0.034126 +0.11999 +0.34757 +0.24802 +0.21159 +0.38783 +0.15002 +0.19716 +0.26151 +0.2804 +0.25433 +0.20779 +0.19208 +0.17772 +0.19412 +0.22198 +0.15677 +0.29006 +0.28531 +0.25209 +0.29258 +0.32834 +0.30742 +0.11164 +0.069628 +0.35451 +0.35735 +0.31798 +0.33606 +0.20549 +0.215 +0.23751 +0.26805 +0.087387 +0.094948 +0.039248 +0.08467 +0.06456 +0.22913 +0.20194 +0.10104 +0.23508 +0.23241 +0.26624 +0.14266 +0.09373 +0.095851 +0.054171 +0.047412 +0.17431 +0.18525 +0.18518 +0.21435 +0.20976 +0.2279 +0.19672 +0.093418 +0.11423 +0.08518 +0.039301 +0.065881 +0.039427 +0.14278 +0.27958 +0.23774 +0.1912 +0.19876 +0.16258 +0.24391 +0.29942 +0.24273 +0.20058 +0.21115 +0.13576 +0.23664 +0.20348 +0.23609 +0.0001 +0.29062 +0.26663 +0.31226 +0.31704 +0.33593 +0.32944 +0.30254 +0.36515 +0.32942 +0.33411 +0.33331 +0.21566 +0.21151 +0.23054 +0.23602 +0.10369 +0.014954 +0.042838 +0.06059 +0.11598 +0.12476 +0.00369 +0.15918 +0.088163 +0.20037 +0.27513 +0.27874 +0.26595 +0.24281 +0.25979 +0.26717 +0.21138 +0.15245 +0.17722 +0.16675 +0.1977 +0.26362 +0.20758 +0.065604 +0.11382 +0.066266 +0.002024 +0.053744 +0.063225 +0.04603 +0.093819 +0.24596 +0.20993 +0.21019 +0.17442 +0.22453 +0.26606 +0.24677 +0.19767 +0.21098 +0.26155 +0.20409 +0.18645 +0.19883 +0.0001 +0.14355 +0.26362 +0.30627 +0.30778 +0.30701 +0.32062 +0.30747 +0.37572 +0.36387 +0.038605 +0.20315 +0.21982 +0.21845 +0.23774 +0.22642 +0.28307 +0.041568 +0.077838 +0.031005 +0.09386 +0.086383 +0.088681 +0.066761 +0.042958 +0.084416 +0.14074 +0.27411 +0.27106 +0.28317 +0.27705 +0.30526 +0.29905 +0.18781 +0.18425 +0.15497 +0.20193 +0.027274 +0.071968 +0.088385 +0.12876 +0.10643 +0.035202 +0.11031 +0.11723 +0.055626 +0.063213 +0.092387 +0.19961 +0.2391 +0.16991 +0.16264 +0.25587 +0.23838 +0.20805 +0.20443 +0.1755 +0.17621 +0.35202 +0.0001 +0.19013 +0.17299 +0.16817 +0.28729 +0.2615 +0.29417 +0.30232 +0.2734 +0.11262 +0.084469 +0.19369 +0.22921 +0.2449 +0.2121 +0.25798 +0.25538 +0.28808 +0.034594 +0.04797 +0.1019 +0.10751 +0.094182 +0.097474 +0.045743 +0.002873 +0.056976 +0.13389 +0.1865 +0.29568 +0.22633 +0.26359 +0.30363 +0.31388 +0.17053 +0.15033 +0.18166 +0.21322 +0.20087 +0.067547 +0.050292 +0.094798 +0.12527 +0.13188 +0.10698 +0.06742 +0.12879 +0.079287 +0.11672 +0.17117 +0.23857 +0.15591 +0.14125 +0.25074 +0.22607 +0.19605 +0.1704 +0.20902 +0.14768 +0.18582 +0.2081 +0.16935 +0.14971 +0.17805 +0.30048 +0.28993 +0.28791 +0.30279 +0.26482 +0.26297 +0.22908 +0.29398 +0.27441 +0.24461 +0.19917 +0.24454 +0.26634 +0.28343 +0.069244 +0.008628 +0.14044 +0.15017 +0.027018 +0.088333 +0.038441 +0.2389 +0.19039 +0.18491 +0.17195 +0.22871 +0.2193 +0.20887 +0.18214 +0.3018 +0.17706 +0.17165 +0.1666 +0.17152 +0.18832 +0.07472 +0.057556 +0.06327 +0.16123 +0.12046 +0.20677 +0.052798 +0.1042 +0.098459 +0.04832 +0.1667 +0.21838 +0.15644 +0.12085 +0.2769 +0.24762 +0.24788 +0.19649 +0.17668 +0.15072 +0.17638 +0.19662 +0.21079 +0.14808 +0.19206 +0.21377 +0.12885 +0.26824 +0.27003 +0.27981 +0.23442 +0.28611 +0.28303 +0.27039 +0.21564 +0.18714 +0.26039 +0.27559 +0.085295 +0.086071 +0.1038 +0.081813 +0.096553 +0.018755 +0.043115 +0.22022 +0.2256 +0.19006 +0.16373 +0.17712 +0.22656 +0.27855 +0.15452 +0.15838 +0.13803 +0.12213 +0.11941 +0.1354 +0.14763 +0.17844 +0.16584 +0.006388 +0.059432 +0.10019 +0.1404 +0.20951 +0.20774 +0.10771 +0.29728 +0.25888 +0.25177 +0.22468 +0.16082 +0.3231 +0.26145 +0.26022 +0.25198 +0.23165 +0.18065 +0.2062 +0.21594 +0.27995 +0.20193 +0.15373 +0.15439 +0.34253 +0.12084 +0.28379 +0.29173 +0.2695 +0.24913 +0.27397 +0.28333 +0.27529 +0.24488 +0.1745 +0.28465 +0.049465 +0.069251 +0.066179 +0.088024 +0.0001 +0.10066 +0.024447 +0.069745 +0.25234 +0.16603 +0.20861 +0.17486 +0.19515 +0.2345 +0.2586 +0.29956 +0.17163 +0.16776 +0.11879 +0.10044 +0.14014 +0.12688 +0.16328 +0.17662 +0.062394 +0.077214 +0.1369 +0.0982 +0.096153 +0.22463 +0.18076 +0.24914 +0.2373 +0.2111 +0.25376 +0.30058 +0.30773 +0.22592 +0.26688 +0.21815 +0.19756 +0.17786 +0.21749 +0.25117 +0.2745 +0.27812 +0.18466 +0.1357 +0.34635 +0.28218 +0.29157 +0.26946 +0.27133 +0.27256 +0.29473 +0.29576 +0.29368 +0.23186 +0.19957 +0.0412 +0.073723 +0.090608 +0.10541 +0.13541 +0.0001 +0.11832 +0.0001 +0.0001 +0.0001 +0.19527 +0.22559 +0.2043 +0.30316 +0.26999 +0.28733 +0.29743 +0.29225 +0.20276 +0.20796 +0.19705 +0.14019 +0.14084 +0.17991 +0.17824 +0.1815 +0.19577 +0.19211 +0.22029 +0.2479 +0.2227 +0.2756 +0.24697 +0.22509 +0.08327 +0.086882 +0.025937 +0.0001 +0.24593 +0.2432 +0.30397 +0.16681 +0.11773 +0.15083 +0.23563 +0.24121 +0.31302 +0.23361 +0.23509 +0.32973 +0.25676 +0.23854 +0.2914 +0.27955 +0.29694 +0.23221 +0.30655 +0.23155 +0.23818 +0.20733 +0.028879 +0.038443 +0.11713 +0.12 +0.079753 +0.0001 +0.054565 +0.16805 +0.02066 +0.0001 +0.039062 +0.22676 +0.21151 +0.33714 +0.32039 +0.27895 +0.26652 +0.28034 +0.24421 +0.10028 +0.17445 +0.14018 +0.17328 +0.20145 +0.19954 +0.31002 +0.30679 +0.32854 +0.27851 +0.33545 +0.084464 +0.066914 +0.25188 +0.20766 +0.17664 +0.070439 +0.047506 +0.040095 +0.25767 +0.28777 +0.27703 +0.26282 +0.11638 +0.14376 +0.10966 +0.22495 +0.26938 +0.21669 +0.21973 +0.21246 +0.25315 +0.26858 +0.25068 +0.28034 +0.28958 +0.21735 +0.26413 +0.21804 +0.21223 +0.21058 +0.063711 +0.061425 +0.092777 +0.052314 +0.12536 +0.087468 +0.142 +0.10151 +0.0001 +0.0001 +0.049792 +0.18209 +0.26159 +0.28818 +0.31721 +0.32836 +0.3002 +0.26318 +0.20218 +0.10485 +0.12238 +0.14116 +0.17442 +0.23757 +0.28735 +0.29045 +0.33944 +0.022346 +0.015904 +0.040725 +0.070406 +0.2282 +0.251 +0.19849 +0.13726 +0.089487 +0.045611 +0.04611 +0.24552 +0.28996 +0.28095 +0.24829 +0.27724 +0.23677 +0.1212 +0.15459 +0.22277 +0.19673 +0.23825 +0.25499 +0.2035 +0.23918 +0.20954 +0.29196 +0.29293 +0.22276 +0.22251 +0.22675 +0.20435 +0.079081 +0.10753 +0.11236 +0.084465 +0.073989 +0.041911 +0.078336 +0.1171 +0.023753 +0.0001 +0.0001 +0.27301 +0.27427 +0.279 +0.32627 +0.29395 +0.34297 +0.29048 +0.25694 +0.10608 +0.11005 +0.13622 +0.33199 +0.28149 +0.2151 +0.11571 +0.10355 +0.11559 +0.062352 +0.0923 +0.064315 +0.029329 +0.22031 +0.25523 +0.22559 +0.082344 +0.01927 +0.051679 +0.071536 +0.071189 +0.063424 +0.25215 +0.23669 +0.25104 +0.23971 +0.2698 +0.22665 +0.20162 +0.14926 +0.2354 +0.27607 +0.23798 +0.23503 +0.21392 +0.26649 +0.26539 +0.21895 +0.20635 +0.241 +0.23534 +0.05383 +0.061898 +0.076024 +0.048422 +0.037149 +0.076475 +0.11521 +0.13093 +0.071075 +0.22676 +0.22273 +0.2897 +0.34479 +0.27758 +0.31131 +0.31334 +0.33555 +0.28904 +0.24032 +0.22544 +0.37981 +0.376 +0.30895 +0.26282 +0.17055 +0.062979 +0.056553 +0.056888 +0.12411 +0.097737 +0.12926 +0.17863 +0.23647 +0.22863 +0.24414 +0.075868 +0.0001 +0.0001 +0.03865 +0.00602 +0.052969 +0.077649 +0.24581 +0.2452 +0.25236 +0.27748 +0.24804 +0.2439 +0.14757 +0.19204 +0.19318 +0.24019 +0.22478 +0.20407 +0.12649 +0.18698 +0.23364 +0.18636 +0.2246 +0.23758 +0.23163 +0.064655 +0.041687 +0.066346 +0.092811 +0.02945 +0.081379 +0.16852 +0.32823 +0.24474 +0.25324 +0.26755 +0.36962 +0.31394 +0.29906 +0.3646 +0.31879 +0.33521 +0.18532 +0.19689 +0.35804 +0.35036 +0.29867 +0.2944 +0.009296 +0.092114 +0.11088 +0.033724 +0.054195 +0.10109 +0.18893 +0.19421 +0.20367 +0.20066 +0.0001 +0.015837 +0.026605 +0.03934 +0.031435 +0.24936 +0.10128 +0.078063 +0.066014 +0.2489 +0.27082 +0.22836 +0.2731 +0.22839 +0.18401 +0.20622 +0.17533 +0.18954 +0.25811 +0.20475 +0.11431 +0.19692 +0.23018 +0.25484 +0.17757 +0.19255 +0.23963 +0.19933 +0.062663 +0.046407 +0.26834 +0.2887 +0.2559 +0.3152 +0.33252 +0.28498 +0.25813 +0.28724 +0.34138 +0.31931 +0.26194 +0.36947 +0.34277 +0.22733 +0.22531 +0.21554 +0.14651 +0.29472 +0.3059 +0.28352 +0.31719 +0.069765 +0.082299 +0.20763 +0.23161 +0.1699 +0.17633 +0.19683 +0.21505 +0.07185 +0.0001 +0.030053 +0.029563 +0.0001 +0.06016 +0.26221 +0.15614 +0.065875 +0.069109 +0.18444 +0.25087 +0.25392 +0.29635 +0.19734 +0.18669 +0.22042 +0.20972 +0.16329 +0.20035 +0.27873 +0.1261 +0.16136 +0.20367 +0.26446 +0.23768 +0.16879 +0.11892 +0.16233 +0.23597 +0.26706 +0.27194 +0.30517 +0.24738 +0.31105 +0.18913 +0.21944 +0.26448 +0.28373 +0.24723 +0.25903 +0.019384 +0.4 +0.4 +0.4 +0.22698 +0.20455 +0.18538 +0.28167 +0.30444 +0.28913 +0.27962 +0.25741 +0.26557 +0.24391 +0.20105 +0.19428 +0.04815 +0.10321 +0.099139 +0.04826 +0.063793 +0.009682 +0.020765 +0.02969 +0.021224 +0.27869 +0.12735 +0.0001 +0.019467 +0.15161 +0.19862 +0.24107 +0.28198 +0.1685 +0.16353 +0.19082 +0.1889 +0.17386 +0.21013 +0.27887 +0.33531 +0.13373 +0.17578 +0.21584 +0.31667 +0.33519 +0.37398 +0.26445 +0.26534 +0.26284 +0.2583 +0.051835 +0.12903 +0.16055 +0.1993 +0.2255 +0.26106 +0.28961 +0.10894 +0.155 +0.069906 +0.4 +0.4 +0.4 +0.4 +0.19193 +0.19973 +0.11948 +0.033237 +0.29386 +0.27708 +0.26132 +0.27075 +0.24973 +0.12171 +0.063793 +0.0001 +0.062313 +0.21545 +0.12098 +0.11913 +0.059555 +0.03259 +0.065308 +0.003063 +0.30817 +0.11822 +0.21804 +0.23534 +0.14242 +0.19826 +0.21337 +0.24511 +0.22029 +0.17365 +0.19032 +0.22849 +0.17614 +0.25335 +0.27494 +0.3237 +0.18066 +0.28004 +0.30674 +0.30158 +0.31098 +0.37589 +0.24973 +0.24864 +0.21922 +0.25405 +0.065824 +0.12574 +0.1477 +0.17999 +0.22573 +0.046688 +0.076829 +0.14944 +0.14066 +0.16661 +0.18217 +0.12223 +0.4 +0.4 +0.4 +0.2274 +0.16564 +0.058034 +0.15392 +0.25511 +0.24532 +0.25316 +0.043978 +0.065449 +0.048977 +0.072629 +0.1165 +0.11408 +0.14642 +0.11171 +0.043268 +0.011695 +0.021028 +0.0001 +0.35874 +0.067389 +0.20809 +0.20257 +0.15515 +0.20202 +0.23445 +0.22696 +0.19785 +0.23241 +0.20782 +0.23199 +0.18573 +0.24571 +0.289 +0.28745 +0.18488 +0.31906 +0.28463 +0.2841 +0.22703 +0.2444 +0.24297 +0.24882 +0.2516 +0.23337 +0.12274 +0.1488 +0.16167 +0.17505 +0.17752 +0.065365 +0.044503 +0.10529 +0.11901 +0.16826 +0.15126 +0.16635 +0.13488 +0.4 +0.4 +0.4 +0.16057 +0.046422 +0.14115 +0.1004 +0.22788 +0.24408 +0.27074 +0.12387 +0.092939 +0.094349 +0.15336 +0.14574 +0.13146 +0.052083 +0.069239 +0.030315 +0.017243 +0.018326 +0.025589 +0.03944 +0.024206 +0.21929 +0.26249 +0.27982 +0.25873 +0.24103 +0.21129 +0.20632 +0.2249 +0.22916 +0.18622 +0.21579 +0.22857 +0.32709 +0.22378 +0.23448 +0.27759 +0.3142 +0.31875 +0.24939 +0.24503 +0.26434 +0.26704 +0.020028 +0.06662 +0.17132 +0.14497 +0.16838 +0.18551 +0.06787 +0.049901 +0.056812 +0.15909 +0.19424 +0.17922 +0.20008 +0.14331 +0.4 +0.4 +0.4 +0.4 +0.39228 +0.15482 +0.11289 +0.066404 +0.22531 +0.26567 +0.18613 +0.14584 +0.075679 +0.092485 +0.056233 +0.063004 +0.088861 +0.045028 +0.043275 +0.028568 +0.055803 +0.19296 +0.02442 +0.21402 +0.24366 +0.30112 +0.27954 +0.29277 +0.2591 +0.20829 +0.20697 +0.17036 +0.18544 +0.18859 +0.15205 +0.22484 +0.31073 +0.21321 +0.25789 +0.27427 +0.32007 +0.28851 +0.2122 +0.2489 +0.28519 +0.077723 +0.049849 +0.031919 +0.17362 +0.14364 +0.171 +0.1698 +0.04863 +0.046593 +0.070034 +0.17611 +0.16809 +0.15707 +0.18626 +0.10319 +0.4 +0.4 +0.4 +0.4 +0.4 +0.4 +0.089589 +0.046888 +0.10281 +0.26974 +0.27713 +0.11872 +0.1517 +0.12461 +0.091822 +0.14553 +0.09018 +0.11702 +0.035033 +0.075164 +0.044238 +0.1972 +0.18189 +0.22415 +0.27006 +0.29219 +0.26524 +0.29042 +0.26329 +0.223 +0.20214 +0.18957 +0.16092 +0.16668 +0.24386 +0.20377 +0.15875 +0.2101 +0.25827 +0.26654 +0.26648 +0.31314 +0.27597 +0.27944 +0.10163 +0.14124 +0.15055 +0.10903 +0.092503 +0.16233 +0.20725 +0.21249 +0.009571 +0.21498 +0.2224 +0.1703 +0.17239 +0.15883 +0.20224 +0.4 +0.4 +0.4 +0.4 +0.4 +0.4 +0.4 +0.3432 +0.035645 +0.080126 +0.24337 +0.24499 +0.041423 +0.098495 +0.11653 +0.087324 +0.059468 +0.11843 +0.13826 +0.045758 +0.076767 +0.049184 +0.2283 +0.17584 +0.27593 +0.27979 +0.25432 +0.28679 +0.27734 +0.26251 +0.24113 +0.22682 +0.17789 +0.15286 +0.22842 +0.21911 +0.21395 +0.1924 +0.19807 +0.24909 +0.28514 +0.2996 +0.22226 +0.27699 +0.29791 +0.27637 +0.26181 +0.0001 +0.043771 +0.024712 +0.20011 +0.1956 +0.19912 +0.25309 +0.17693 +0.20036 +0.17115 +0.154 +0.16949 +0.4 +0.4 +0.4 +0.4 +0.4 +0.4 +0.4 +0.38269 +0.37629 +0.035356 +0.086719 +0.28206 +0.20747 +0.19312 +0.039957 +0.070189 +0.014627 +0.050677 +0.13601 +0.052103 +0.060834 +0.092128 +0.10926 +0.17939 +0.17615 +0.28152 +0.27635 +0.23853 +0.30349 +0.27961 +0.22762 +0.21873 +0.16402 +0.14766 +0.20391 +0.20911 +0.1799 +0.23463 +0.21166 +0.21996 +0.2879 +0.356 +0.22725 +0.32336 +0.21886 +0.26311 +0.17919 +0.14765 +0.26707 +0.10845 +0.038083 +0.092908 +0.19809 +0.22939 +0.24669 +0.23665 +0.20539 +0.18334 +0.14876 +0.16006 +0.4 +0.4 +0.4 +0.4 +0.4 +0.4 +0.4 +0.36784 +0.080638 +0.040387 +0.19447 +0.25097 +0.2191 +0.18679 +0.27398 +0.058985 +0.084637 +0.0001 +0.11942 +0.029852 +0.001867 +0.087224 +0.027983 +0.16964 +0.21681 +0.26222 +0.30976 +0.24012 +0.29626 +0.20877 +0.26429 +0.25535 +0.23316 +0.25172 +0.2477 +0.19335 +0.21852 +0.22615 +0.23246 +0.25597 +0.24872 +0.21321 +0.2143 +0.31558 +0.23962 +0.21685 +0.19438 +0.154 +0.26926 +0.18693 +0.098917 +0.24513 +0.23241 +0.23132 +0.21771 +0.23616 +0.29169 +0.18394 +0.16833 +0.4 +0.4 +0.4 +0.4 +0.4 +0.4 +0.4 +0.37046 +0.34215 +0.35729 +0.19292 +0.19526 +0.27837 +0.22547 +0.21347 +0.2779 +0.10025 +0.11967 +0.076624 +0.059866 +0.054003 +0.027284 +0.032438 +0.10629 +0.16227 +0.23904 +0.26197 +0.3107 +0.29245 +0.29439 +0.20577 +0.25721 +0.22897 +0.24901 +0.23689 +0.24226 +0.20912 +0.2138 +0.20976 +0.26029 +0.27561 +0.27212 +0.24421 +0.25492 +0.26649 +0.23726 +0.25972 +0.069638 +0.079311 +0.27343 +0.20568 +0.14542 +0.16654 +0.27873 +0.25754 +0.23826 +0.23927 +0.27164 +0.4 +0.4 +0.4 +0.4 +0.4 +0.4 +0.4 +0.4 +0.4 +0.36166 +0.35146 +0.14308 +0.17662 +0.17877 +0.22655 +0.24904 +0.24148 +0.27066 +0.087658 +0.13103 +0.10522 +0.18804 +0.14017 +0.098434 +0.072404 +0.10766 +0.18637 +0.27832 +0.27508 +0.31655 +0.29596 +0.30656 +0.20235 +0.18748 +0.20844 +0.24154 +0.2064 +0.20226 +0.1942 +0.38502 +0.32953 +0.22716 +0.23376 +0.28177 +0.28624 +0.24582 +0.26963 +0.27104 +0.28029 +0.017862 +0.30459 +0.3125 +0.26022 +0.20966 +0.25075 +0.13337 +0.1944 +0.24735 +0.22587 +0.21349 +0.4 +0.4 +0.4 +0.4 +0.4 +0.4 +0.4 +0.4 +0.4 +0.37513 +0.082183 +0.10759 +0.07137 +0.15351 +0.23985 +0.24658 +0.24331 +0.29621 +0.096342 +0.1308 +0.14311 +0.039666 +0.18966 +0.3128 +0.3117 +0.082324 +0.24084 +0.28169 +0.26432 +0.28601 +0.25083 +0.30556 +0.24075 +0.23148 +0.17736 +0.24723 +0.23152 +0.26062 +0.25218 +0.2524 +0.27725 +0.20217 +0.20604 +0.044 +0.2912 +0.21762 +0.25438 +0.26495 +0.25751 +0.049575 +0.27891 +0.33978 +0.34393 +0.068802 +0.25076 +0.26801 +0.28593 +0.25114 +0.27167 +0.20538 +0.4 +0.4 +0.4 +0.4 +0.4 +0.4 +0.4 +0.4 +0.4 +0.059715 +0.064167 +0.082028 +0.052115 +0.12636 +0.23266 +0.22564 +0.24754 +0.28126 +0.24987 +0.12442 +0.10923 +0.050323 +0.23166 +0.37012 +0.31211 +0.25567 +0.23423 +0.26474 +0.27755 +0.25026 +0.23443 +0.15873 +0.22719 +0.19563 +0.19339 +0.23197 +0.20779 +0.24396 +0.20782 +0.24963 +0.2844 +0.21566 +0.1942 +0.089295 +0.28661 +0.20955 +0.25888 +0.27519 +0.11221 +0.059831 +0.29958 +0.34686 +0.32322 +0.23402 +0.20874 +0.15551 +0.2539 +0.16434 +0.27812 +0.21523 +0.4 +0.4 +0.4 +0.4 +0.4 +0.4 +0.4 +0.0639 +0.049292 +0.026705 +0.084781 +0.087055 +0.090262 +0.15219 +0.2142 +0.20138 +0.23924 +0.25565 +0.23935 +0.089425 +0.069929 +0.054533 +0.036286 +0.39497 +0.3796 +0.24705 +0.22575 +0.27204 +0.24579 +0.23865 +0.22741 +0.20116 +0.20533 +0.18939 +0.19735 +0.2278 +0.20797 +0.22936 +0.22696 +0.27159 +0.28909 +0.19631 +0.16408 +0.28965 +0.25284 +0.18506 +0.22081 +0.28238 +0.099248 +0.26954 +0.32286 +0.31717 +0.24655 +0.19565 +0.2471 +0.16252 +0.1666 +0.17232 +0.25129 +0.21711 +0.23758 +0.2672 +0.4 +0.4 +0.4 +0.4 +0.042058 +0.011017 +0.0606 +0.034737 +0.1335 +0.091107 +0.064815 +0.15884 +0.20372 +0.21863 +0.21932 +0.24272 +0.20875 +0.15754 +0.041663 +0.067638 +0.001851 +0.33668 +0.32938 +0.26947 +0.22514 +0.19502 +0.22561 +0.22891 +0.10505 +0.19682 +0.16932 +0.19009 +0.21151 +0.22163 +0.20847 +0.23715 +0.20981 +0.24241 +0.25683 +0.17053 +0.13335 +0.29984 +0.25091 +0.25553 +0.30865 +0.32135 +0.043546 +0.29666 +0.32851 +0.24497 +0.25052 +0.22096 +0.22595 +0.20424 +0.1841 +0.16686 +0.22859 +0.21484 +0.21319 +0.28979 +0.27169 +0.4 +0.4 +0.4 +0.086344 +0.11402 +0.095525 +0.10889 +0.1177 +0.11593 +0.19047 +0.13995 +0.15798 +0.19863 +0.23017 +0.24491 +0.22093 +0.10011 +0.059856 +0.0001 +0.039673 +0.005489 +0.29375 +0.29493 +0.23755 +0.22281 +0.16461 +0.16856 +0.15057 +0.17198 +0.16215 +0.17929 +0.22017 +0.23689 +0.27231 +0.22294 +0.21787 +0.24907 +0.23862 +0.18108 +0.29998 +0.29084 +0.2637 +0.26334 +0.33428 +0.32415 +0.33541 +0.24684 +0.27458 +0.22553 +0.2446 +0.16451 +0.21686 +0.27142 +0.28318 +0.2541 +0.21404 +0.19828 +0.2424 +0.26162 +0.2517 +0.4 +0.4 +0.25465 +0.21907 +0.039554 +0.061751 +0.020393 +0.27632 +0.2274 +0.23605 +0.17007 +0.16245 +0.19405 +0.24418 +0.27125 +0.12732 +0.045922 +0.024951 +0.069058 +0.045562 +0.059325 +0.05068 +0.28133 +0.25373 +0.12504 +0.15551 +0.17028 +0.20591 +0.17752 +0.14094 +0.17373 +0.2229 +0.23907 +0.22535 +0.20991 +0.25016 +0.24083 +0.22763 +0.3096 +0.30591 +0.26671 +0.25564 +0.19365 +0.18465 +0.2186 +0.27065 +0.25687 +0.27858 +0.22116 +0.20674 +0.24023 +0.23909 +0.28626 +0.25297 +0.24543 +0.24935 +0.20405 +0.20802 +0.226 +0.23723 +0.18575 +0.22989 +0.22737 +0.19662 +0.20422 +0.042669 +0.34212 +0.2673 +0.26459 +0.25702 +0.16491 +0.18016 +0.1807 +0.19648 +0.13669 +0.16472 +0.098392 +0.052895 +0.045123 +0.021693 +0.060092 +0.24678 +0.27739 +0.19046 +0.10739 +0.18048 +0.19893 +0.20863 +0.19743 +0.17053 +0.18526 +0.204 +0.23558 +0.20542 +0.21198 +0.26651 +0.20475 +0.22414 +0.22879 +0.24927 +0.22204 +0.21863 +0.23906 +0.19324 +0.2146 +0.2973 +0.30382 +0.27602 +0.24649 +0.19694 +0.22972 +0.26809 +0.25731 +0.23305 +0.24143 +0.28043 +0.26114 +0.16721 +0.23633 +0.2236 +0.18461 +0.20562 +0.22046 +0.24532 +0.19239 +0.097143 +0.34556 +0.25837 +0.28556 +0.2135 +0.16521 +0.19438 +0.18885 +0.071609 +0.12606 +0.13055 +0.06514 +0.037243 +0.079155 +0.049216 +0.27572 +0.25673 +0.27187 +0.20097 +0.12279 +0.16373 +0.21186 +0.22959 +0.17316 +0.19509 +0.25776 +0.19855 +0.24293 +0.25064 +0.24341 +0.1818 +0.19124 +0.23987 +0.19803 +0.19588 +0.22911 +0.20462 +0.27267 +0.21715 +0.22803 +0.31041 +0.30431 +0.27686 +0.21595 +0.19626 +0.225 +0.28098 +0.27705 +0.24881 +0.30426 +0.30309 +0.2753 +0.15512 +0.16557 +0.14609 +0.21019 +0.3046 +0.27045 +0.30048 +0.29603 +0.22878 +0.35357 +0.2428 +0.26207 +0.22594 +0.22116 +0.21133 +0.20457 +0.10642 +0.091056 +0.11216 +0.10485 +0.10553 +0.11743 +0.052611 +0.32715 +0.26998 +0.27234 +0.18814 +0.13967 +0.1731 +0.24302 +0.20375 +0.17752 +0.18096 +0.19017 +0.21841 +0.28306 +0.21842 +0.21831 +0.21479 +0.20435 +0.24165 +0.18662 +0.18696 +0.20743 +0.20999 +0.26271 +0.28767 +0.34753 +0.31907 +0.28509 +0.28342 +0.22408 +0.22263 +0.22997 +0.2514 +0.2718 +0.24386 +0.29352 +0.28497 +0.26714 +0.22179 +0.19873 +0.15657 +0.23051 +0.27596 +0.30504 +0.28163 +0.31738 +0.24404 +0.20001 +0.24823 +0.24558 +0.26287 +0.23036 +0.17403 +0.19941 +0.050924 +0.11065 +0.12107 +0.11141 +0.081339 +0.066512 +0.26681 +0.33245 +0.2842 +0.27137 +0.13443 +0.12913 +0.20533 +0.22011 +0.13017 +0.11093 +0.2009 +0.16434 +0.16682 +0.052556 +0.2039 +0.18248 +0.23259 +0.24115 +0.23623 +0.16859 +0.18305 +0.20801 +0.23508 +0.21253 +0.27014 +0.31203 +0.35376 +0.31431 +0.2338 +0.23649 +0.20114 +0.24904 +0.27671 +0.28702 +0.21107 +0.28452 +0.28879 +0.28583 +0.22705 +0.1733 +0.14382 +0.2103 +0.29096 +0.27108 +0.29298 +0.30401 +0.33294 +0.2661 +0.24448 +0.28769 +0.2846 +0.21796 +0.1904 +0.17201 +0.10335 +0.15279 +0.09758 +0.10919 +0.22781 +0.24458 +0.28638 +0.33623 +0.26354 +0.24627 +0.13793 +0.16786 +0.20963 +0.26192 +0.26424 +0.078547 +0.20785 +0.1753 +0.17123 +0.18745 +0.18756 +0.17492 +0.22538 +0.26895 +0.20251 +0.15969 +0.17051 +0.224 +0.24175 +0.27208 +0.29042 +0.27663 +0.32708 +0.3178 +0.22683 +0.19648 +0.14041 +0.25868 +0.28105 +0.29419 +0.28283 +0.29695 +0.30245 +0.2978 +0.2906 +0.1981 +0.16803 +0.24519 +0.27542 +0.3077 +0.28637 +0.28655 +0.31056 +0.3215 +0.26266 +0.28935 +0.26316 +0.21067 +0.26529 +0.21233 +0.21661 +0.19514 +0.058764 +0.095952 +0.26307 +0.26454 +0.3431 +0.28543 +0.24604 +0.24178 +0.16132 +0.12676 +0.18738 +0.26456 +0.2734 +0.25374 +0.2496 +0.16043 +0.16439 +0.16392 +0.18246 +0.20061 +0.23457 +0.23644 +0.26248 +0.16564 +0.16922 +0.26509 +0.22617 +0.24431 +0.28032 +0.22873 +0.30997 +0.35124 +0.17794 +0.12749 +0.12642 +0.22598 +0.24194 +0.34815 +0.29204 +0.30573 +0.28563 +0.3306 +0.29288 +0.11272 +0.21624 +0.23665 +0.27594 +0.32638 +0.29868 +0.27684 +0.32359 +0.32615 +0.27699 +0.093678 +0.22258 +0.22179 +0.26242 +0.208 +0.22812 +0.23699 +0.16543 +0.23743 +0.25243 +0.27368 +0.28585 +0.25623 +0.24315 +0.24721 +0.2009 +0.09905 +0.27669 +0.27937 +0.24965 +0.2249 +0.20758 +0.22531 +0.026543 +0.17961 +0.1834 +0.17872 +0.19935 +0.21975 +0.26382 +0.18182 +0.19333 +0.24686 +0.24728 +0.27399 +0.22227 +0.2375 +0.31757 +0.23422 +0.19158 +0.13802 +0.091129 +0.23055 +0.22843 +0.38364 +0.32999 +0.29403 +0.25914 +0.34479 +0.14366 +0.096603 +0.24232 +0.24135 +0.28144 +0.31116 +0.28451 +0.29222 +0.327 +0.32076 +0.10187 +0.11556 +0.149 +0.17823 +0.24983 +0.26294 +0.20567 +0.22444 +0.15083 +0.18216 +0.22019 +0.25496 +0.27533 +0.25284 +0.23961 +0.2682 +0.1896 +0.35851 +0.28976 +0.25593 +0.23812 +0.21789 +0.23051 +0.26807 +0.15912 +0.21587 +0.21464 +0.18868 +0.21642 +0.24188 +0.2658 +0.18379 +0.19472 +0.24407 +0.25069 +0.30199 +0.27188 +0.23512 +0.050702 +0.21101 +0.15248 +0.15695 +0.10133 +0.20271 +0.25374 +0.37427 +0.31265 +0.32181 +0.30432 +0.36288 +0.10581 +0.064 +0.21683 +0.21304 +0.28924 +0.30933 +0.24238 +0.3751 +0.36663 +0.35283 +0.026858 +0.088392 +0.088532 +0.10536 +0.23959 +0.26668 +0.16009 +0.19648 +0.13436 +0.18868 +0.19615 +0.24397 +0.26222 +0.27437 +0.25259 +0.25773 +0.13399 +0.09073 +0.25029 +0.26663 +0.23337 +0.18326 +0.23492 +0.27099 +0.077225 +0.085638 +0.22964 +0.17419 +0.1997 +0.18 +0.22251 +0.2026 +0.17983 +0.24912 +0.21202 +0.29351 +0.23388 +0.21137 +0.21194 +0.17867 +0.16706 +0.14751 +0.12714 +0.23477 +0.27704 +0.35896 +0.3312 +0.36014 +0.29811 +0.4 +0.37374 +0.069552 +0.11239 +0.21512 +0.2466 +0.28578 +0.23592 +0.35841 +0.35292 +0.30578 +0.049787 +0.0449 +0.10198 +0.12548 +0.12556 +0.27626 +0.17783 +0.2087 +0.16387 +0.21948 +0.22865 +0.21411 +0.20818 +0.28317 +0.26076 +0.26818 +0.13274 +0.13517 +0.26171 +0.23888 +0.20687 +0.16933 +0.23147 +0.22617 +0.32896 +0.33398 +0.048516 +0.13146 +0.18492 +0.18295 +0.21446 +0.16603 +0.17788 +0.26636 +0.22855 +0.27601 +0.32689 +0.33932 +0.20881 +0.17398 +0.081212 +0.22825 +0.25023 +0.28211 +0.35723 +0.39711 +0.32471 +0.35208 +0.34391 +0.39655 +0.38175 +0.22254 +0.27198 +0.24592 +0.27069 +0.30404 +0.22167 +0.35156 +0.35757 +0.33445 +0.10337 +0.10007 +0.075821 +0.09285 +0.055982 +0.2604 +0.23222 +0.21608 +0.1939 +0.24387 +0.21957 +0.23855 +0.21798 +0.24022 +0.29823 +0.29378 +0.15567 +0.17091 +0.26224 +0.27008 +0.23497 +0.19207 +0.23586 +0.19968 +0.19159 +0.35638 +0.31608 +0.060707 +0.1711 +0.17634 +0.18162 +0.19817 +0.19598 +0.2623 +0.24653 +0.27275 +0.31587 +0.30608 +0.20973 +0.278 +0.30811 +0.23051 +0.25413 +0.2484 +0.35951 +0.38832 +0.33628 +0.37431 +0.3345 +0.36701 +0.37054 +0.31962 +0.26556 +0.26924 +0.26879 +0.28947 +0.37366 +0.34729 +0.33704 +0.3149 +0.15206 +0.11532 +0.10718 +0.069033 +0.24055 +0.22819 +0.23653 +0.22236 +0.18356 +0.23204 +0.1937 +0.22733 +0.19671 +0.2397 +0.19054 +0.18418 +0.18055 +0.17752 +0.16987 +0.28501 +0.25941 +0.23391 +0.25561 +0.23954 +0.22069 +0.22438 +0.31867 +0.1519 +0.21386 +0.20374 +0.19902 +0.18698 +0.21433 +0.26059 +0.25112 +0.30125 +0.2984 +0.19204 +0.30285 +0.28035 +0.27562 +0.2491 +0.24241 +0.26127 +0.35206 +0.38744 +0.3307 +0.36306 +0.33042 +0.34068 +0.29603 +0.30634 +0.2769 +0.29619 +0.28987 +0.38986 +0.37057 +0.3897 +0.33359 +0.33877 +0.073638 +0.070933 +0.063204 +0.24965 +0.26395 +0.22775 +0.26542 +0.25807 +0.21247 +0.20077 +0.18942 +0.182 +0.18675 +0.24101 +0.20627 +0.18434 +0.21604 +0.215 +0.18487 +0.24652 +0.2539 +0.2761 +0.28169 +0.23656 +0.22883 +0.26819 +0.20928 +0.13107 +0.1583 +0.21302 +0.22812 +0.21141 +0.1809 +0.17728 +0.23325 +0.25637 +0.29496 +0.3202 +0.29128 +0.26617 +0.28934 +0.30587 +0.25756 +0.34153 +0.3454 +0.36789 +0.36487 +0.35781 +0.29844 +0.096507 +0.33336 +0.28063 +0.30533 +0.28655 +0.10919 +0.37463 +0.35592 +0.34192 +0.36046 +0.34868 +0.050824 +0.036656 +0.23391 +0.23369 +0.27145 +0.27087 +0.27429 +0.22722 +0.19948 +0.22722 +0.19125 +0.20495 +0.15349 +0.20367 +0.21245 +0.16264 +0.20687 +0.21336 +0.19001 +0.22701 +0.21024 +0.21339 +0.32917 +0.10801 +0.20716 +0.24352 +0.19288 +0.10097 +0.15817 +0.19957 +0.22183 +0.18119 +0.16287 +0.16047 +0.2075 +0.27991 +0.27785 +0.304 +0.29934 +0.22419 +0.16489 +0.12435 +0.22362 +0.29856 +0.31298 +0.35951 +0.36334 +0.22721 +0.10883 +0.061217 +0.30417 +0.3093 +0.28867 +0.029891 +0.34534 +0.33983 +0.35913 +0.33733 +0.35835 +0.36969 +0.35345 +0.24495 +0.24662 +0.2242 +0.27165 +0.25938 +0.23773 +0.20812 +0.22896 +0.229 +0.20803 +0.20281 +0.19852 +0.16723 +0.17933 +0.14036 +0.25283 +0.21414 +0.22556 +0.22718 +0.2047 +0.26121 +0.25705 +0.27392 +0.2137 +0.24536 +0.19131 +0.12063 +0.18234 +0.18564 +0.26406 +0.15782 +0.16322 +0.16716 +0.23627 +0.30324 +0.27684 +0.31126 +0.29241 +0.23577 +0.20948 +0.17087 +0.22218 +0.28748 +0.30429 +0.3488 +0.32492 +0.20779 +0.11444 +0.22278 +0.29746 +0.3119 +0.27085 +0.03317 +0.09853 +0.30823 +0.32495 +0.34078 +0.334 +0.34456 +0.24341 +0.26256 +0.25058 +0.27482 +0.28622 +0.24628 +0.21757 +0.21165 +0.2398 +0.30966 +0.33049 +0.27203 +0.22158 +0.18739 +0.1818 +0.15547 +0.23725 +0.22511 +0.22229 +0.22345 +0.21574 +0.27858 +0.27375 +0.22794 +0.22671 +0.23186 +0.18037 +0.10708 +0.21341 +0.31233 +0.28461 +0.28901 +0.13517 +0.18768 +0.20861 +0.30722 +0.32851 +0.3221 +0.26064 +0.26949 +0.23151 +0.22642 +0.24524 +0.27487 +0.031952 +0.32205 +0.33839 +0.32368 +0.23633 +0.27337 +0.25235 +0.10182 +0.021788 +0.25256 +0.24288 +0.31357 +0.33282 +0.31452 +0.31294 +0.34574 +0.38951 +0.27053 +0.29173 +0.3061 +0.288 +0.080375 +0.074662 +0.066508 +0.077573 +0.26051 +0.30003 +0.23637 +0.19266 +0.17204 +0.15526 +0.15571 +0.18549 +0.15987 +0.27772 +0.21841 +0.16688 +0.22062 +0.29532 +0.32993 +0.24095 +0.20953 +0.23598 +0.20681 +0.28843 +0.29404 +0.31153 +0.31305 +0.28609 +0.26051 +0.20456 +0.21565 +0.32051 +0.31613 +0.30792 +0.28406 +0.25476 +0.22905 +0.25591 +0.09576 +0.060041 +0.31898 +0.33655 +0.25528 +0.2946 +0.27807 +0.18608 +0.11974 +0.1267 +0.2381 +0.32767 +0.32004 +0.3301 +0.33199 +0.35893 +0.346 +0.38933 +0.1121 +0.11382 +0.0001 +0.026722 +0.081457 +0.09921 +0.10377 +0.12797 +0.25021 +0.2857 +0.26252 +0.22412 +0.18012 +0.1591 +0.14153 +0.22241 +0.26346 +0.27527 +0.28475 +0.21175 +0.1964 +0.28752 +0.32533 +0.32277 +0.34175 +0.23356 +0.16674 +0.14536 +0.30912 +0.35536 +0.30513 +0.30323 +0.24435 +0.20623 +0.087074 +0.19702 +0.33023 +0.25722 +0.28918 +0.26411 +0.23223 +0.26483 +0.079659 +0.10597 +0.060134 +0.30373 +0.22869 +0.27865 +0.26523 +0.25956 +0.12271 +0.1112 +0.1717 +0.33316 +0.28019 +0.31122 +0.33946 +0.34824 +0.36335 +0.38569 +0.098692 +0.014943 +0.0001 +0.0001 +0.007921 +0.11374 +0.14358 +0.10504 +0.059295 +0.23879 +0.25552 +0.23491 +0.20748 +0.18576 +0.14749 +0.23775 +0.25935 +0.29344 +0.26125 +0.21144 +0.18766 +0.30627 +0.32275 +0.31755 +0.33047 +0.23328 +0.16645 +0.12168 +0.16237 +0.37329 +0.29094 +0.32095 +0.22263 +0.23022 +0.25034 +0.23148 +0.20706 +0.22841 +0.23456 +0.2638 +0.22662 +0.30368 +0.19647 +0.087223 +0.007069 +0.07115 +0.21373 +0.24737 +0.21993 +0.24996 +0.23577 +0.19992 +0.20957 +0.25329 +0.29403 +0.3428 +0.33746 +0.3118 +0.33005 +0.35214 +0.11261 +0.06633 +0.039907 +0.011341 +0.054709 +0.03307 +0.12673 +0.12387 +0.098226 +0.21418 +0.21398 +0.23672 +0.23048 +0.17397 +0.14556 +0.201 +0.29325 +0.29753 +0.20432 +0.22793 +0.25217 +0.2973 +0.32138 +0.29657 +0.32387 +0.23244 +0.17451 +0.13533 +0.33328 +0.32392 +0.28829 +0.30719 +0.22463 +0.21999 +0.20797 +0.24265 +0.22846 +0.054169 +0.22683 +0.235 +0.28251 +0.27405 +0.28729 +0.24807 +0.072141 +0.20065 +0.12611 +0.26892 +0.24626 +0.25017 +0.21956 +0.22171 +0.21921 +0.20754 +0.26148 +0.3391 +0.3422 +0.32238 +0.12436 +0.12807 +0.084041 +0.10693 +0.0001 +0.038668 +0.036953 +0.0001 +0.065521 +0.10375 +0.21245 +0.23927 +0.20152 +0.24221 +0.24704 +0.19453 +0.16866 +0.22642 +0.26392 +0.26336 +0.19401 +0.2217 +0.25674 +0.28858 +0.29224 +0.2754 +0.32549 +0.2528 +0.31121 +0.21556 +0.2917 +0.29979 +0.29563 +0.29823 +0.2414 +0.20859 +0.19401 +0.27263 +0.24046 +0.21075 +0.25847 +0.19814 +0.2954 +0.29314 +0.28422 +0.24334 +0.20192 +0.18599 +0.26401 +0.25595 +0.24509 +0.22951 +0.25988 +0.21216 +0.2176 +0.20803 +0.24535 +0.33515 +0.23967 +0.20322 +0.13064 +0.18833 +0.096679 +0.10258 +0.043267 +0.057132 +0.0001 +0.0001 +0.034578 +0.080525 +0.21888 +0.2316 +0.1878 +0.27851 +0.26458 +0.20002 +0.17412 +0.22833 +0.2359 +0.26649 +0.20602 +0.23089 +0.24477 +0.29291 +0.29806 +0.27908 +0.32952 +0.27044 +0.33076 +0.28322 +0.28203 +0.33973 +0.26406 +0.27088 +0.24229 +0.23061 +0.19545 +0.087169 +0.05468 +0.039091 +0.014275 +0.24778 +0.16168 +0.15496 +0.28167 +0.2525 +0.20105 +0.2013 +0.23534 +0.25158 +0.26757 +0.23633 +0.28009 +0.20994 +0.21195 +0.19935 +0.24256 +0.30897 +0.07907 +0.20569 +0.2599 +0.11067 +0.018214 +0.0001 +0.016239 +0.035038 +0.01959 +0.040685 +0.021912 +0.13251 +0.23492 +0.20922 +0.22635 +0.30566 +0.25936 +0.16321 +0.1582 +0.25826 +0.29236 +0.27182 +0.17888 +0.28172 +0.34766 +0.32263 +0.26806 +0.26558 +0.3503 +0.29236 +0.27736 +0.26497 +0.24355 +0.33691 +0.25026 +0.27255 +0.21902 +0.2697 +0.088447 +0.052836 +0.10955 +0.01446 +0.002116 +0.0001 +0.22394 +0.1634 +0.14138 +0.13303 +0.19761 +0.17252 +0.18496 +0.25271 +0.26125 +0.24843 +0.30567 +0.23711 +0.21823 +0.20457 +0.26492 +0.29542 +0.15171 +0.07061 +0.087443 +0.25344 +0.23487 +0.007284 +0.005826 +0.072397 +0.067566 +0.056776 +0.030822 +0.11795 +0.21513 +0.2501 +0.21779 +0.28062 +0.23538 +0.20818 +0.20604 +0.23086 +0.30109 +0.25941 +0.21122 +0.33388 +0.34261 +0.32938 +0.28392 +0.25683 +0.31339 +0.31412 +0.28249 +0.27619 +0.25919 +0.27117 +0.23928 +0.2574 +0.24176 +0.19981 +0.0001 +0.047075 +0.033595 +0.0001 +0.0001 +0.0001 +0.2121 +0.18284 +0.13621 +0.14561 +0.13095 +0.1435 +0.20248 +0.19201 +0.29067 +0.27145 +0.33488 +0.2149 +0.35731 +0.063148 +0.16415 +0.30425 +0.27855 +0.27291 +0.078221 +0.24409 +0.27461 +0.086283 +0.081187 +0.069993 +0.070227 +0.080777 +0.035938 +0.056604 +0.23391 +0.21853 +0.21174 +0.29599 +0.23822 +0.23131 +0.23553 +0.23556 +0.25862 +0.22411 +0.29099 +0.30104 +0.34389 +0.33863 +0.29165 +0.25414 +0.24149 +0.27723 +0.32329 +0.2713 +0.30033 +0.25988 +0.18424 +0.12665 +0.1994 +0.23211 +0.18883 +0.0997 +0.30794 +0.28135 +0.30003 +0.30513 +0.21295 +0.18138 +0.23998 +0.12238 +0.14847 +0.1458 +0.24955 +0.20274 +0.25195 +0.27162 +0.20243 +0.2794 +0.32181 +0.28542 +0.14981 +0.14998 +0.27611 +0.28379 +0.23913 +0.26597 +0.26624 +0.10352 +0.13882 +0.026945 +0.017382 +0.11045 +0.10978 +0.30117 +0.24519 +0.23407 +0.20722 +0.25279 +0.24599 +0.25389 +0.19934 +0.25297 +0.15481 +0.26795 +0.28397 +0.28304 +0.33856 +0.35456 +0.3337 +0.25733 +0.23708 +0.30296 +0.30148 +0.050383 +0.21421 +0.20627 +0.20622 +0.16119 +0.21083 +0.22976 +0.33964 +0.32545 +0.26559 +0.26515 +0.30701 +0.21285 +0.21763 +0.19885 +0.20582 +0.26494 +0.15045 +0.13982 +0.25107 +0.22016 +0.25453 +0.22415 +0.16145 +0.27035 +0.30937 +0.29012 +0.33032 +0.14088 +0.16448 +0.12768 +0.27743 +0.21701 +0.20857 +0.212 +0.10783 +0.10183 +0.11479 +0.12074 +0.29172 +0.31315 +0.26914 +0.22523 +0.19722 +0.2363 +0.23827 +0.24961 +0.24468 +0.2504 +0.10529 +0.24491 +0.25603 +0.28475 +0.33781 +0.32939 +0.26564 +0.22699 +0.20762 +0.23677 +0.25056 +0.27112 +0.26125 +0.23034 +0.23303 +0.18802 +0.18902 +0.3164 +0.32392 +0.34719 +0.23468 +0.24198 +0.2353 +0.23133 +0.24606 +0.17241 +0.20559 +0.25972 +0.2782 +0.12885 +0.25218 +0.21907 +0.24489 +0.25801 +0.17496 +0.032743 +0.023565 +0.31408 +0.28416 +0.2855 +0.31484 +0.1101 +0.11096 +0.18171 +0.22298 +0.2327 +0.15019 +0.29087 +0.12925 +0.2783 +0.26323 +0.26638 +0.22904 +0.23315 +0.21531 +0.26487 +0.22541 +0.26176 +0.20017 +0.18361 +0.12137 +0.19501 +0.26154 +0.25613 +0.38526 +0.35632 +0.26748 +0.24513 +0.20147 +0.1983 +0.23295 +0.26819 +0.25501 +0.23283 +0.21931 +0.18856 +0.3385 +0.34026 +0.342 +0.31147 +0.26065 +0.23113 +0.26605 +0.25543 +0.24361 +0.17445 +0.17563 +0.21013 +0.2544 +0.27304 +0.24638 +0.2286 +0.28128 +0.28615 +0.19899 +0.048957 +0.045531 +0.0001 +0.33483 +0.26154 +0.34864 +0.33013 +0.17825 +0.20738 +0.26197 +0.1829 +0.27727 +0.30801 +0.23985 +0.22202 +0.24985 +0.24594 +0.21238 +0.23388 +0.21992 +0.22497 +0.26183 +0.25137 +0.042815 +0.22264 +0.15133 +0.21361 +0.28987 +0.30748 +0.3534 +0.32398 +0.26834 +0.24725 +0.19673 +0.22364 +0.20503 +0.20758 +0.19572 +0.19919 +0.1904 +0.2954 +0.34468 +0.31029 +0.32819 +0.26466 +0.23541 +0.21377 +0.25632 +0.24383 +0.18545 +0.16135 +0.17005 +0.18956 +0.24671 +0.252 +0.26218 +0.30439 +0.28985 +0.18489 +0.21648 +0.041318 +0.092712 +0.066144 +0.29798 +0.34907 +0.28579 +0.1896 +0.18917 +0.097665 +0.050431 +0.018204 +0.27504 +0.27283 +0.24073 +0.20517 +0.21785 +0.2379 +0.19742 +0.22385 +0.26031 +0.24348 +0.30288 +0.2763 +0.30023 +0.17557 +0.18126 +0.23658 +0.3425 +0.27313 +0.031816 +0.032984 +0.29661 +0.27721 +0.22227 +0.23159 +0.18944 +0.17404 +0.15503 +0.20092 +0.20941 +0.33007 +0.35916 +0.18746 +0.20009 +0.27279 +0.24854 +0.21219 +0.25294 +0.088953 +0.077796 +0.25382 +0.22287 +0.17789 +0.23359 +0.21946 +0.11495 +0.28549 +0.23777 +0.1704 +0.23307 +0.25261 +0.2519 +0.29963 +0.33107 +0.36481 +0.35589 +0.37036 +0.4 +0.4 +0.4 +0.18577 +0.2106 +0.30427 +0.24745 +0.14014 +0.19702 +0.20436 +0.20864 +0.31266 +0.30103 +0.23889 +0.29877 +0.27093 +0.28207 +0.26095 +0.15411 +0.21668 +0.13423 +0.21062 +0.022725 +0.038918 +0.20671 +0.25975 +0.21827 +0.22764 +0.21267 +0.15286 +0.11538 +0.19249 +0.20432 +0.31556 +0.3654 +0.19881 +0.19716 +0.25998 +0.25463 +0.22484 +0.29169 +0.29761 +0.26936 +0.20763 +0.19981 +0.20221 +0.14217 +0.21361 +0.13374 +0.2314 +0.21411 +0.20268 +0.24305 +0.22177 +0.26205 +0.28802 +0.11192 +0.077037 +0.053057 +0.4 +0.4 +0.4 +0.4 +0.4 +0.23055 +0.24516 +0.24323 +0.19243 +0.21227 +0.20562 +0.28351 +0.20637 +0.26967 +0.284 +0.25899 +0.29453 +0.04807 +0.2664 +0.37872 +0.19465 +0.14993 +0.22163 +0.11122 +0.21567 +0.22612 +0.1799 +0.23288 +0.19205 +0.26723 +0.1219 +0.11536 +0.18551 +0.18788 +0.28727 +0.31843 +0.21063 +0.20485 +0.24317 +0.25937 +0.24852 +0.32001 +0.26685 +0.28674 +0.21991 +0.22076 +0.175 +0.16512 +0.16812 +0.039856 +0.24663 +0.2179 +0.23736 +0.18861 +0.23062 +0.062332 +0.068167 +0.07122 +0.10733 +0.0001 +0.007449 +0.29675 +0.4 +0.4 +0.4 +0.4 +0.22207 +0.23112 +0.20694 +0.24136 +0.2245 +0.20135 +0.25995 +0.045065 +0.069958 +0.023766 +0.0001 +0.013156 +0.19359 +0.4 +0.30645 +0.15873 +0.20199 +0.11066 +0.18125 +0.20765 +0.16556 +0.22124 +0.17988 +0.26242 +0.33294 +0.11139 +0.15225 +0.18319 +0.2132 +0.29643 +0.19547 +0.26788 +0.2864 +0.24884 +0.29256 +0.30287 +0.28296 +0.27699 +0.20405 +0.23872 +0.14838 +0.0001 +0.25344 +0.26798 +0.23509 +0.24777 +0.22103 +0.18227 +0.07652 +0.032325 +0.10412 +0.12459 +0.049662 +0.058835 +0.04383 +0.30459 +0.24959 +0.3884 +0.38296 +0.36417 +0.36251 +0.25834 +0.20981 +0.23855 +0.24514 +0.26823 +0.20369 +0.16882 +0.066668 +0.064846 +0.013689 +0.032038 +0.35008 +0.35797 +0.31069 +0.29249 +0.25862 +0.094015 +0.083049 +0.18502 +0.13035 +0.15857 +0.21203 +0.2992 +0.34086 +0.12363 +0.16402 +0.185 +0.21618 +0.28466 +0.23036 +0.28584 +0.26642 +0.23913 +0.2763 +0.31229 +0.29428 +0.19312 +0.18958 +0.016123 +0.2483 +0.21116 +0.26792 +0.27557 +0.29392 +0.2475 +0.20129 +0.068408 +0.077786 +0.067485 +0.022065 +0.064429 +0.0001 +0.023867 +0.22012 +0.27249 +0.23648 +0.37839 +0.33437 +0.3663 +0.36982 +0.2708 +0.22968 +0.26221 +0.3523 +0.27648 +0.026637 +0.025591 +0.16834 +0.024246 +0.002478 +0.0001 +0.34026 +0.33446 +0.34141 +0.26267 +0.27059 +0.22655 +0.077379 +0.1629 +0.13222 +0.17987 +0.27183 +0.29695 +0.31706 +0.13584 +0.15324 +0.14486 +0.25539 +0.19882 +0.12354 +0.31897 +0.27887 +0.24691 +0.31833 +0.35117 +0.26118 +0.25864 +0.042058 +0.030788 +0.26489 +0.22118 +0.28077 +0.074916 +0.053434 +0.28587 +0.21088 +0.094293 +0.099078 +0.081569 +0.035512 +0.051782 +0.0001 +0.05769 +0.22765 +0.2737 +0.21671 +0.38157 +0.36069 +0.32881 +0.36491 +0.2655 +0.326 +0.32513 +0.31495 +0.3024 +0.2733 +0.057404 +0.12893 +0.070567 +0.023793 +0.030308 +0.33378 +0.34735 +0.30906 +0.32356 +0.23738 +0.21411 +0.28408 +0.28776 +0.26348 +0.33971 +0.26488 +0.28246 +0.13479 +0.16056 +0.14683 +0.14222 +0.00981 +0.053193 +0.14667 +0.28908 +0.31064 +0.27178 +0.32002 +0.30553 +0.2656 +0.24093 +0.054197 +0.034824 +0.24662 +0.21711 +0.28218 +0.062809 +0.28275 +0.28134 +0.2229 +0.19733 +0.10236 +0.089712 +0.09131 +0.071544 +0.028618 +0.069352 +0.071875 +0.30433 +0.28024 +0.38253 +0.4 +0.35452 +0.363 +0.17254 +0.1879 +0.32279 +0.29991 +0.32479 +0.25374 +0.27343 +0.089295 +0.14473 +0.12867 +0.089765 +0.32265 +0.37299 +0.33686 +0.33737 +0.30005 +0.33775 +0.28924 +0.17773 +0.24845 +0.35136 +0.25216 +0.15643 +0.1384 +0.14205 +0.15376 +0.15203 +0.06325 +0.053392 +0.19373 +0.22679 +0.17251 +0.29946 +0.30395 +0.35886 +0.32598 +0.27933 +0.22537 +0.23675 +0.24155 +0.2459 +0.28134 +0.028757 +0.11636 +0.26094 +0.21531 +0.245 +0.11331 +0.074273 +0.021055 +0.27119 +0.24237 +0.27491 +0.26702 +0.31016 +0.26559 +0.21529 +0.39587 +0.37703 +0.35539 +0.15841 +0.2127 +0.10647 +0.30868 +0.31575 +0.30839 +0.28581 +0.30744 +0.11383 +0.058999 +0.055503 +0.34043 +0.4 +0.32828 +0.31885 +0.31415 +0.1683 +0.21356 +0.21248 +0.23038 +0.31683 +0.33532 +0.3054 +0.312 +0.19126 +0.15052 +0.17042 +0.015128 +0.29672 +0.19629 +0.18241 +0.13783 +0.20325 +0.31189 +0.39083 +0.33512 +0.33041 +0.29113 +0.2167 +0.23272 +0.22402 +0.065266 +0.058641 +0.26048 +0.21191 +0.2183 +0.2422 +0.24273 +0.23717 +0.28794 +0.28348 +0.25522 +0.29128 +0.26761 +0.21753 +0.18844 +0.20067 +0.17694 +0.38034 +0.4 +0.36518 +0.36223 +0.19499 +0.29628 +0.30463 +0.29273 +0.31043 +0.29682 +0.1256 +0.087186 +0.1182 +0.33019 +0.4 +0.30499 +0.307 +0.19165 +0.18022 +0.20787 +0.22091 +0.4 +0.32878 +0.32337 +0.29767 +0.29565 +0.25698 +0.32532 +0.21823 +0.1259 +0.24692 +0.19023 +0.19725 +0.1845 +0.22477 +0.24228 +0.38117 +0.33264 +0.31186 +0.30613 +0.24022 +0.22143 +0.20197 +0.064677 +0.022436 +0.056288 +0.22377 +0.21984 +0.31065 +0.31617 +0.3484 +0.38249 +0.32277 +0.32387 +0.31471 +0.077633 +0.24024 +0.21413 +0.17263 +0.32877 +0.33967 +0.38318 +0.33898 +0.38044 +0.22421 +0.053981 +0.26763 +0.30334 +0.32148 +0.32888 +0.26565 +0.14594 +0.12076 +0.3079 +0.39101 +0.21099 +0.16204 +0.13908 +0.17466 +0.18255 +0.21338 +0.38975 +0.31972 +0.34732 +0.31622 +0.28224 +0.27622 +0.2786 +0.23477 +0.26572 +0.21813 +0.18159 +0.20794 +0.23865 +0.31748 +0.19807 +0.1647 +0.34384 +0.31377 +0.30574 +0.21768 +0.19915 +0.18035 +0.085467 +0.052067 +0.21901 +0.21712 +0.29518 +0.29089 +0.28255 +0.33872 +0.24066 +0.25305 +0.28276 +0.1256 +0.099953 +0.2216 +0.22644 +0.21221 +0.34787 +0.36518 +0.39527 +0.34791 +0.39161 +0.2279 +0.056402 +0.13299 +0.32002 +0.28942 +0.33555 +0.30478 +0.16203 +0.1475 +0.29677 +0.28093 +0.24827 +0.18157 +0.1521 +0.16444 +0.1932 +0.2116 +0.23729 +0.29677 +0.37988 +0.30478 +0.28339 +0.25567 +0.31298 +0.26369 +0.26835 +0.242 +0.1687 +0.26803 +0.23652 +0.31127 +0.33246 +0.15271 +0.33712 +0.30438 +0.30286 +0.23003 +0.14431 +0.20672 +0.25927 +0.18149 +0.21968 +0.22317 +0.29412 +0.28125 +0.32257 +0.28824 +0.24728 +0.25739 +0.0001 +0.048539 +0.060858 +0.078375 +0.24214 +0.3401 +0.34583 +0.33681 +0.38162 +0.36261 +0.37406 +0.25974 +0.23799 +0.10727 +0.30752 +0.26546 +0.31037 +0.31446 +0.28469 +0.080744 +0.27694 +0.20373 +0.24161 +0.21086 +0.17187 +0.17727 +0.21521 +0.22742 +0.0001 +0.2757 +0.33667 +0.30781 +0.30562 +0.21539 +0.30431 +0.27169 +0.28232 +0.22798 +0.21737 +0.16957 +0.097303 +0.29528 +0.29843 +0.31813 +0.16003 +0.27942 +0.28424 +0.23073 +0.29818 +0.38142 +0.2452 +0.18874 +0.22311 +0.23868 +0.12949 +0.13008 +0.32653 +0.29002 +0.076296 +0.040473 +0.0001 +0.0001 +0.029249 +0.057263 +0.31907 +0.33274 +0.36105 +0.35688 +0.36219 +0.34065 +0.32994 +0.25256 +0.26722 +0.24908 +0.30251 +0.26093 +0.2918 +0.30025 +0.32848 +0.074898 +0.22417 +0.17486 +0.22654 +0.19959 +0.19977 +0.19956 +0.20298 +0.21641 +0.23463 +0.28687 +0.19081 +0.30214 +0.31095 +0.27425 +0.32626 +0.31673 +0.304 +0.23334 +0.267 +0.19594 +0.31885 +0.30954 +0.28289 +0.36666 +0.37723 +0.13338 +0.29098 +0.32083 +0.31976 +0.3711 +0.21649 +0.12256 +0.12089 +0.1599 +0.099952 +0.27218 +0.2923 +0.2981 +0.01672 +0.046593 +0.014831 +0.020652 +0.02976 +0.27954 +0.27952 +0.31493 +0.36439 +0.35907 +0.3291 +0.33052 +0.25287 +0.22029 +0.24375 +0.24109 +0.29851 +0.298 +0.26266 +0.28485 +0.32375 +0.052186 +0.24282 +0.2194 +0.19987 +0.30434 +0.20184 +0.20264 +0.21906 +0.20576 +0.21237 +0.2866 +0.23653 +0.31733 +0.29393 +0.29147 +0.37668 +0.33016 +0.30908 +0.23404 +0.20536 +0.22737 +0.29675 +0.26037 +0.28754 +0.39294 +0.37095 +0.1485 +0.14444 +0.2414 +0.2337 +0.27535 +0.19591 +0.12779 +0.10369 +0.1646 +0.10988 +0.26852 +0.29194 +0.0001 +0.021117 +0.043858 +0.051763 +0.0001 +0.24326 +0.24458 +0.25531 +0.3224 +0.28098 +0.31827 +0.27235 +0.26463 +0.2262 +0.21161 +0.22106 +0.2368 +0.22408 +0.27363 +0.24481 +0.30304 +0.34155 +0.052966 +0.2099 +0.17514 +0.31255 +0.20094 +0.19032 +0.21649 +0.17756 +0.20101 +0.22727 +0.27761 +0.24425 +0.31766 +0.34126 +0.29164 +0.36879 +0.28438 +0.28244 +0.23667 +0.19307 +0.18774 +0.38872 +0.26523 +0.30547 +0.35032 +0.14108 +0.12885 +0.1455 +0.25727 +0.24014 +0.15188 +0.22297 +0.1339 +0.13018 +0.18696 +0.28413 +0.29274 +0.2689 +0.0001 +0.038052 +0.084013 +0.001213 +0.017729 +0.21405 +0.26445 +0.273 +0.31445 +0.32467 +0.29194 +0.21573 +0.25812 +0.24693 +0.065937 +0.19608 +0.22603 +0.22539 +0.19272 +0.28512 +0.27017 +0.33909 +0.039837 +0.1273 +0.2784 +0.31858 +0.19508 +0.1907 +0.19013 +0.20395 +0.19591 +0.24251 +0.26201 +0.23578 +0.33042 +0.34849 +0.2954 +0.32173 +0.27733 +0.26062 +0.26311 +0.20233 +0.22517 +0.34497 +0.0001 +0.27847 +0.33438 +0.13911 +0.13138 +0.13989 +0.1687 +0.2295 +0.18446 +0.15646 +0.23837 +0.22701 +0.2802 +0.29309 +0.3033 +0.26886 +0.037871 +0.025418 +0.0001 +0.0001 +0.19211 +0.22254 +0.24079 +0.27385 +0.29917 +0.13699 +0.24215 +0.22131 +0.22712 +0.29374 +0.25656 +0.026052 +0.23296 +0.23404 +0.19862 +0.21958 +0.21177 +0.35954 +0.0001 +0.18949 +0.23177 +0.30985 +0.28077 +0.19745 +0.26164 +0.24228 +0.19952 +0.21941 +0.26196 +0.22967 +0.25413 +0.35979 +0.28781 +0.090248 +0.28164 +0.29839 +0.2733 +0.21876 +0.25797 +0.4 +0.2867 +0.28329 +0.29778 +0.13409 +0.16461 +0.15537 +0.1676 +0.15695 +0.32675 +0.17434 +0.21576 +0.32218 +0.25443 +0.30041 +0.26543 +0.24651 +0.057455 +0.082285 +0.070295 +0.25037 +0.22051 +0.20612 +0.23638 +0.27466 +0.33484 +0.15001 +0.25151 +0.2782 +0.221 +0.27923 +0.23118 +0.19473 +0.22352 +0.24358 +0.23519 +0.19929 +0.21696 +0.07882 +0.000271 +0.19543 +0.21875 +0.1737 +0.070113 +0.32095 +0.25158 +0.21892 +0.20533 +0.24959 +0.25499 +0.21701 +0.29944 +0.26635 +0.058452 +0.030062 +0.27602 +0.28655 +0.27882 +0.27778 +0.24901 +0.3045 +0.28805 +0.29816 +0.19423 +0.16696 +0.14737 +0.15951 +0.14558 +0.15926 +0.30282 +0.16179 +0.2151 +0.28788 +0.30244 +0.22407 +0.28214 +0.22807 +0.26636 +0.03327 +0.26985 +0.25247 +0.2348 +0.1815 +0.23134 +0.064489 +0.20273 +0.13122 +0.067282 +0.30582 +0.23098 +0.22978 +0.20543 +0.22822 +0.21696 +0.20984 +0.23964 +0.2264 +0.20811 +0.20503 +0.0001 +0.17321 +0.20719 +0.16694 +0.26812 +0.30269 +0.25417 +0.2408 +0.24335 +0.2304 +0.25116 +0.24217 +0.32381 +0.24025 +0.22159 +0.0001 +0.31699 +0.26535 +0.25777 +0.27604 +0.28875 +0.29341 +0.33023 +0.16375 +0.19459 +0.15114 +0.12374 +0.15878 +0.11887 +0.1076 +0.29717 +0.34563 +0.23372 +0.29592 +0.29128 +0.24289 +0.21105 +0.003778 +0.28342 +0.28354 +0.23392 +0.28661 +0.23113 +0.21713 +0.20606 +0.083148 +0.12349 +0.020913 +0.02038 +0.34213 +0.16849 +0.15582 +0.17529 +0.18691 +0.21054 +0.20419 +0.19984 +0.17723 +0.19068 +0.21072 +0.23299 +0.22846 +0.27042 +0.26866 +0.26701 +0.26515 +0.24798 +0.24446 +0.20885 +0.25424 +0.27769 +0.26732 +0.35506 +0.26411 +0.24735 +0.19713 +0.26197 +0.27352 +0.29865 +0.23755 +0.27054 +0.25882 +0.1983 +0.1664 +0.18954 +0.14376 +0.1523 +0.16175 +0.25518 +0.29463 +0.3035 +0.33048 +0.26118 +0.27514 +0.2755 +0.27248 +0.22868 +0.34256 +0.043476 +0.046579 +0.22706 +0.2773 +0.27017 +0.21002 +0.20534 +0.045605 +0.020938 +0.10195 +0.13219 +0.11271 +0.14464 +0.17279 +0.18958 +0.20152 +0.22703 +0.20219 +0.0001 +0.17718 +0.1877 +0.21227 +0.22769 +0.3177 +0.30992 +0.28405 +0.30128 +0.29853 +0.24845 +0.21277 +0.18167 +0.15153 +0.21412 +0.29822 +0.29256 +0.28075 +0.26645 +0.19703 +0.23959 +0.27397 +0.2441 +0.23874 +0.25762 +0.26528 +0.22048 +0.18381 +0.18855 +0.17835 +0.016348 +0.27357 +0.24519 +0.30448 +0.26721 +0.14478 +0.11623 +0.27654 +0.2618 +0.23272 +0.23001 +0.21545 +0.074554 +0.080653 +0.33962 +0.24983 +0.18679 +0.25013 +0.2147 +0.22531 +0.071346 +0.11859 +0.13176 +0.10862 +0.1232 +0.14788 +0.19831 +0.2098 +0.19245 +0.012965 +0.0001 +0.011781 +0.22723 +0.21371 +0.21559 +0.31809 +0.28274 +0.28816 +0.29941 +0.28891 +0.33095 +0.23908 +0.24069 +0.18913 +0.20231 +0.17075 +0.27295 +0.30005 +0.29024 +0.21239 +0.2419 +0.24422 +0.25407 +0.21351 +0.25499 +0.25113 +0.20932 +0.1807 +0.16941 +0.34131 +0.31974 +0.28046 +0.25789 +0.28586 +0.055653 +0.075477 +0.095851 +0.30894 +0.27929 +0.21959 +0.21923 +0.24989 +0.26777 +0.08997 +0.089782 +0.26374 +0.17088 +0.25484 +0.18812 +0.22542 +0.27834 +0.2324 +0.15838 +0.13037 +0.18015 +0.15461 +0.20546 +0.049631 +0.11941 +0.036244 +0.061906 +0.0001 +0.004824 +0.031653 +0.087849 +0.29362 +0.29748 +0.27905 +0.31139 +0.31516 +0.33641 +0.29479 +0.19285 +0.19304 +0.19814 +0.17731 +0.12793 +0.16297 +0.12301 +0.21856 +0.18229 +0.34293 +0.2241 +0.25895 +0.26563 +0.26037 +0.23228 +0.30635 +0.25565 +0.31445 +0.33104 +0.29386 +0.2586 +0.26248 +0.10823 +0.080935 +0.12493 +0.31188 +0.2908 +0.22048 +0.22308 +0.27721 +0.26877 +0.26246 +0.21179 +0.23956 +0.15582 +0.24697 +0.18038 +0.092531 +0.12991 +0.12579 +0.25696 +0.28532 +0.21118 +0.15801 +0.18805 +0.023119 +0.0001 +0.10754 +0.075582 +0.004586 +0.004153 +0.056244 +0.009258 +0.28919 +0.32831 +0.34556 +0.34601 +0.33297 +0.32378 +0.31513 +0.236 +0.26656 +0.18807 +0.17585 +0.11188 +0.14369 +0.15437 +0.23673 +0.24864 +0.2816 +0.31398 +0.30183 +0.27287 +0.25737 +0.28133 +0.29546 +0.2662 +0.30425 +0.29362 +0.32061 +0.093567 +0.12815 +0.1229 +0.15004 +0.11239 +0.29244 +0.28807 +0.22299 +0.23766 +0.23995 +0.26521 +0.20686 +0.30346 +0.20941 +0.17003 +0.22141 +0.17135 +0.095751 +0.067389 +0.11556 +0.081133 +0.30302 +0.25233 +0.28914 +0.16069 +0.14062 +0.071101 +0.078372 +0.073483 +0.064986 +0.02749 +0.050185 +0.027444 +0.3454 +0.32592 +0.28608 +0.33754 +0.35131 +0.266 +0.31442 +0.24852 +0.25008 +0.21591 +0.14633 +0.13209 +0.14829 +0.13891 +0.13079 +0.28617 +0.22833 +0.30606 +0.25176 +0.22794 +0.25161 +0.27232 +0.30183 +0.29557 +0.30033 +0.31397 +0.052323 +0.11003 +0.11932 +0.07731 +0.074499 +0.14097 +0.29202 +0.28643 +0.19653 +0.27406 +0.21811 +0.24573 +0.17325 +0.004265 +0.20379 +0.17521 +0.22979 +0.20022 +0.20757 +0.078771 +0.048415 +0.080821 +0.056754 +0.07309 +0.24721 +0.23407 +0.15713 +0.035209 +0.070879 +0.13215 +0.065149 +0.080996 +0.092078 +0.074218 +0.20577 +0.29478 +0.30316 +0.30101 +0.32033 +0.24937 +0.26775 +0.23342 +0.21403 +0.18757 +0.15795 +0.14957 +0.16176 +0.10289 +0.12797 +0.27607 +0.23862 +0.28959 +0.27118 +0.27193 +0.23326 +0.26995 +0.30326 +0.30446 +0.27614 +0.34854 +0.11518 +0.17289 +0.15286 +0.038479 +0.075704 +0.078003 +0.097303 +0.26943 +0.26713 +0.3053 +0.25964 +0.25949 +0.20896 +0.02331 +0.049791 +0.17298 +0.20369 +0.19295 +0.16403 +0.15162 +0.24188 +0.13666 +0.054771 +0.067916 +0.16089 +0.23022 +0.24193 +0.23191 +0.19938 +0.12129 +0.071811 +0.10687 +0.039491 +0.0001 +0.031878 +0.20557 +0.27297 +0.29981 +0.3669 +0.39594 +0.24479 +0.21946 +0.20797 +0.18224 +0.18547 +0.1386 +0.14351 +0.12955 +0.24908 +0.29725 +0.23993 +0.24284 +0.29128 +0.30002 +0.22299 +0.25607 +0.27867 +0.27024 +0.31027 +0.22408 +0.25765 +0.16104 +0.086681 +0.12654 +0.10464 +0.24206 +0.27607 +0.31502 +0.28188 +0.35036 +0.29154 +0.24327 +0.20081 +0.15938 +0.25532 +0.094959 +0.20046 +0.19499 +0.179 +0.15896 +0.13255 +0.33896 +0.36808 +0.085008 +0.043541 +0.17549 +0.17714 +0.20171 +0.23591 +0.26209 +0.064579 +0.08987 +0.039286 +0.033799 +0.022537 +0.18552 +0.21207 +0.24824 +0.37311 +0.38124 +0.34084 +0.34958 +0.19062 +0.18452 +0.19615 +0.13854 +0.16726 +0.12352 +0.2524 +0.28961 +0.23755 +0.294 +0.28794 +0.28051 +0.24828 +0.23343 +0.22752 +0.23113 +0.17864 +0.19729 +0.21071 +0.24234 +0.10251 +0.085541 +0.093309 +0.22727 +0.30361 +0.29806 +0.2797 +0.30877 +0.30617 +0.19355 +0.15537 +0.17375 +0.26429 +0.28669 +0.18067 +0.18282 +0.1871 +0.17013 +0.13458 +0.33468 +0.38436 +0.32186 +0.3313 +0.25311 +0.19622 +0.21124 +0.25786 +0.27952 +0.3166 +0.11542 +0.050501 +0.04051 +0.26622 +0.22093 +0.23172 +0.23192 +0.23914 +0.35712 +0.32046 +0.34383 +0.33658 +0.19349 +0.20902 +0.11045 +0.1632 +0.11392 +0.20546 +0.065993 +0.26984 +0.31716 +0.2788 +0.2855 +0.27403 +0.26194 +0.26698 +0.15976 +0.17082 +0.21311 +0.18627 +0.24771 +0.28893 +0.074987 +0.18481 +0.18398 +0.28835 +0.33487 +0.29229 +0.30163 +0.21717 +0.19276 +0.17057 +0.17367 +0.27165 +0.28806 +0.17176 +0.16532 +0.153 +0.16693 +0.088651 +0.12518 +0.34909 +0.31306 +0.36175 +0.23021 +0.22467 +0.15204 +0.25237 +0.29089 +0.3164 +0.027274 +0.000969 +0.001982 +0.27562 +0.24149 +0.21893 +0.2702 +0.25644 +0.22379 +0.27186 +0.30014 +0.32174 +0.35059 +0.23312 +0.2256 +0.13583 +0.28952 +0.2174 +0.24949 +0.27937 +0.32171 +0.2825 +0.26242 +0.25805 +0.28804 +0.27701 +0.24517 +0.19664 +0.20773 +0.16278 +0.25909 +0.28325 +0.12402 +0.17704 +0.17346 +0.31381 +0.3102 +0.28624 +0.28521 +0.21629 +0.17852 +0.16152 +0.20733 +0.045343 +0.077592 +0.13978 +0.16123 +0.17452 +0.12945 +0.099728 +0.33081 +0.36583 +0.2979 +0.34088 +0.19867 +0.15977 +0.13696 +0.26192 +0.29183 +0.27093 +0.078182 +0.048692 +0.035013 +0.22048 +0.20828 +0.21625 +0.24838 +0.23278 +0.25361 +0.26602 +0.29951 +0.29598 +0.30327 +0.27132 +0.23971 +0.32911 +0.12579 +0.1218 +0.29584 +0.28198 +0.32419 +0.24614 +0.24664 +0.25476 +0.30686 +0.23638 +0.30171 +0.17352 +0.26915 +0.22936 +0.25183 +0.28481 +0.18929 +0.19198 +0.18664 +0.30907 +0.33437 +0.29652 +0.13408 +0.17046 +0.15989 +0.14523 +0.18508 +0.19991 +0.14234 +0.15236 +0.17569 +0.16279 +0.14186 +0.072002 +0.3056 +0.36338 +0.31272 +0.13856 +0.19328 +0.21026 +0.18636 +0.25638 +0.29891 +0.0001 +0.0001 +0.061231 +0.061499 +0.23192 +0.18179 +0.23202 +0.22752 +0.22495 +0.23471 +0.23368 +0.21768 +0.25076 +0.23224 +0.26525 +0.25246 +0.30524 +0.30496 +0.18704 +0.29196 +0.3045 +0.30218 +0.23812 +0.2669 +0.23467 +0.29816 +0.29132 +0.22679 +0.2977 +0.30415 +0.21777 +0.09225 +0.12537 +0.1815 +0.19446 +0.20735 +0.27605 +0.28567 +0.060103 +0.11382 +0.17361 +0.16545 +0.13826 +0.17282 +0.18643 +0.20155 +0.1565 +0.20139 +0.15445 +0.12174 +0.32205 +0.32393 +0.16182 +0.14938 +0.16242 +0.17891 +0.20166 +0.18748 +0.067393 +0.052924 +0.0001 +0.0001 +0.10153 +0.083003 +0.17197 +0.20469 +0.19646 +0.24318 +0.21691 +0.27015 +0.23736 +0.21585 +0.24952 +0.23492 +0.23891 +0.26339 +0.30591 +0.25819 +0.17587 +0.31221 +0.30314 +0.30186 +0.26123 +0.28831 +0.24996 +0.33001 +0.27883 +0.28679 +0.28239 +0.22107 +0.26521 +0.070639 +0.14777 +0.16791 +0.2439 +0.20984 +0.2633 +0.044169 +0.069948 +0.049491 +0.17771 +0.19166 +0.13617 +0.17146 +0.20803 +0.28636 +0.22822 +0.19658 +0.15395 +0.34635 +0.32809 +0.13803 +0.18259 +0.14 +0.14672 +0.12216 +0.083255 +0.081877 +0.085277 +0.067064 +0.037438 +0.040225 +0.036183 +0.086034 +0.15515 +0.17809 +0.23337 +0.24638 +0.30555 +0.24833 +0.24478 +0.20518 +0.26357 +0.24826 +0.28415 +0.25959 +0.33043 +0.27602 +0.27977 +0.32841 +0.30268 +0.29239 +0.28993 +0.28532 +0.28875 +0.3639 +0.26128 +0.21562 +0.27914 +0.091206 +0.082528 +0.10132 +0.16333 +0.19754 +0.23611 +0.2384 +0.25859 +0.044452 +0.028833 +0.0001 +0.17574 +0.15733 +0.15391 +0.17802 +0.22596 +0.26922 +0.23202 +0.2004 +0.15586 +0.15884 +0.1982 +0.17488 +0.18443 +0.16087 +0.15905 +0.12676 +0.10411 +0.004997 +0.047565 +0.091766 +0.07026 +0.061582 +0.028085 +0.009847 +0.16174 +0.16884 +0.23983 +0.20044 +0.28364 +0.2487 +0.23761 +0.28256 +0.29039 +0.26157 +0.20254 +0.24996 +0.29674 +0.34029 +0.29873 +0.33945 +0.28756 +0.29233 +0.27965 +0.30425 +0.32071 +0.33224 +0.2827 +0.25967 +0.078258 +0.11733 +0.10103 +0.1532 +0.17738 +0.21637 +0.24047 +0.10522 +0.098695 +0.084956 +0.044311 +0.0001 +0.04512 +0.15432 +0.14655 +0.26871 +0.25104 +0.27235 +0.25788 +0.1607 +0.18909 +0.21178 +0.19198 +0.19167 +0.21016 +0.024161 +0.042042 +0.11632 +0.15313 +0.083352 +0.061332 +0.062033 +0.088549 +0.083708 +0.030844 +0.03871 +0.093835 +0.15061 +0.22703 +0.21105 +0.23777 +0.23369 +0.22348 +0.28228 +0.28036 +0.28695 +0.27076 +0.20816 +0.27672 +0.26314 +0.27774 +0.34398 +0.30155 +0.32559 +0.25364 +0.27372 +0.2726 +0.30868 +0.31997 +0.28557 +0.10574 +0.12587 +0.14032 +0.15908 +0.20959 +0.2261 +0.25228 +0.09257 +0.091821 +0.00544 +0.098801 +0.052131 +0.034978 +0.32173 +0.27513 +0.27686 +0.28196 +0.26358 +0.16894 +0.1864 +0.19465 +0.16822 +0.18154 +0.15998 +0.31884 +0.058708 +0.075721 +0.072739 +0.055151 +0.088133 +0.11464 +0.08773 +0.032783 +0.07611 +0.098682 +0.029645 +0.1181 +0.16586 +0.23162 +0.20041 +0.22239 +0.20483 +0.22631 +0.27058 +0.32601 +0.26968 +0.31918 +0.33567 +0.26513 +0.25751 +0.26146 +0.32755 +0.32933 +0.32432 +0.25083 +0.24927 +0.30992 +0.28669 +0.28756 +0.31826 +0.12601 +0.12009 +0.12959 +0.14988 +0.20385 +0.28263 +0.25277 +0.27347 +0.041372 +0.051799 +0.08779 +0.054085 +0.32885 +0.32079 +0.27715 +0.30507 +0.20492 +0.23659 +0.19157 +0.20381 +0.20349 +0.19898 +0.31065 +0.30025 +0.065132 +0.11507 +0.1268 +0.06978 +0.098154 +0.000559 +0.009784 +0.019661 +0.052294 +0.079918 +0.082371 +0.092684 +0.093299 +0.17526 +0.17483 +0.15336 +0.20833 +0.21643 +0.25187 +0.26861 +0.27066 +0.27694 +0.33105 +0.36747 +0.26619 +0.28439 +0.31184 +0.33757 +0.28825 +0.27646 +0.25737 +0.25481 +0.34623 +0.28896 +0.20833 +0.23254 +0.16669 +0.091768 +0.13925 +0.1416 +0.17542 +0.26039 +0.23932 +0.25942 +0.068885 +0.028661 +0.34463 +0.32265 +0.35274 +0.30336 +0.27304 +0.27346 +0.26089 +0.25579 +0.1753 +0.24914 +0.24599 +0.24782 +0.28731 +0.061436 +0.11794 +0.10406 +0.033471 +0.087101 +0.11234 +0.0001 +0.060055 +0.048104 +0.089312 +0.024873 +0.035104 +0.068793 +0.085135 +0.1321 +0.12484 +0.16453 +0.23174 +0.19657 +0.20591 +0.26503 +0.15836 +0.28359 +0.25727 +0.34335 +0.27218 +0.29823 +0.29887 +0.30451 +0.26737 +0.24409 +0.28271 +0.27459 +0.33288 +0.25617 +0.2245 +0.21388 +0.17517 +0.081404 +0.11188 +0.19133 +0.29134 +0.26615 +0.22878 +0.25547 +0.015252 +0.25994 +0.36472 +0.30566 +0.22599 +0.22872 +0.23466 +0.28759 +0.25612 +0.25886 +0.28014 +0.24162 +0.25683 +0.23031 +0.28827 +0.078547 +0.046156 +0.064222 +0.0001 +0.029972 +0.070715 +0.016699 +0.048382 +0.073467 +0.080614 +0.009339 +0.0001 +0.000539 +0.095081 +0.14696 +0.15425 +0.17155 +0.19552 +0.20491 +0.19648 +0.21444 +0.25638 +0.3019 +0.31311 +0.27272 +0.31942 +0.28813 +0.33043 +0.28633 +0.25296 +0.24602 +0.28643 +0.2307 +0.25601 +0.27198 +0.22627 +0.2353 +0.18475 +0.11887 +0.13505 +0.25712 +0.29905 +0.29014 +0.24308 +0.23669 +0.18697 +0.26138 +0.22816 +0.22038 +0.23992 +0.23525 +0.2299 +0.28728 +0.26245 +0.2809 +0.29061 +0.22411 +0.24905 +0.24777 +0.26118 +0.056835 +0.016486 +0.037831 +0.0001 +0.0001 +0.030391 +0.0001 +0.07138 +0.17088 +0.081756 +0.005509 +0.0001 +0.076787 +0.11324 +0.14809 +0.15223 +0.13736 +0.19167 +0.16185 +0.21253 +0.24244 +0.22782 +0.27566 +0.29368 +0.29316 +0.28281 +0.2967 +0.32633 +0.28569 +0.26816 +0.22618 +0.21894 +0.21531 +0.26706 +0.25522 +0.26856 +0.23766 +0.15645 +0.13402 +0.12838 +0.28324 +0.29781 +0.27975 +0.24096 +0.20743 +0.25189 +0.27396 +0.22738 +0.20824 +0.20936 +0.21952 +0.086842 +0.035232 +0.2483 +0.26635 +0.25876 +0.21988 +0.28051 +0.25052 +0.2718 +0.042661 +0.002153 +0.057242 +0.046652 +0.0001 +0.03887 +0.13176 +0.078474 +0.11201 +0.055036 +0.063983 +0.04826 +0.043991 +0.19746 +0.13718 +0.18064 +0.21238 +0.11488 +0.1301 +0.19995 +0.27837 +0.25768 +0.26723 +0.24406 +0.28068 +0.30995 +0.29087 +0.31377 +0.27654 +0.27095 +0.027297 +0.22499 +0.16603 +0.25111 +0.30207 +0.24176 +0.32309 +0.17129 +0.1515 +0.12689 +0.25841 +0.29334 +0.24254 +0.25156 +0.2166 +0.26148 +0.25615 +0.24186 +0.19827 +0.022891 +0.080331 +0.017243 +0.0001 +0.21829 +0.30202 +0.27576 +0.23998 +0.29561 +0.28915 +0.25364 +0.071623 +0.054216 +0.049665 +0.006147 +0.036134 +0.070422 +0.058376 +0.060452 +0.091808 +0.063578 +0.036646 +0.073358 +0.12375 +0.23194 +0.15261 +0.15782 +0.20592 +0.18537 +0.18954 +0.20783 +0.27142 +0.25789 +0.2709 +0.2596 +0.29518 +0.30272 +0.2656 +0.28019 +0.26542 +0.26914 +0.12387 +0.17181 +0.16518 +0.2667 +0.28604 +0.24478 +0.23407 +0.18 +0.14029 +0.12051 +0.20455 +0.25893 +0.21164 +0.24813 +0.26044 +0.23235 +0.26842 +0.18922 +0.21962 +0.04989 +0.079242 +0.075542 +0.007179 +0.33454 +0.30058 +0.297 +0.2866 +0.27899 +0.29632 +0.26639 +0.2803 +0.031462 +0.031807 +0.041354 +0.050518 +0.067497 +0.034261 +0.029366 +0.090692 +0.091643 +0.025114 +0.038758 +0.09812 +0.25298 +0.26661 +0.4 +0.26297 +0.20199 +0.19656 +0.22467 +0.20129 +0.25261 +0.20958 +0.26311 +0.29087 +0.28816 +0.26418 +0.27994 +0.25916 +0.2995 +0.1392 +0.16368 +0.18324 +0.23899 +0.29226 +0.27643 +0.33204 +0.18151 +0.13439 +0.13246 +0.2069 +0.27373 +0.23054 +0.28664 +0.23234 +0.26881 +0.16997 +0.19104 +0.21108 +0.013669 +0.11145 +0.072926 +0.31642 +0.3073 +0.3182 +0.28882 +0.31676 +0.30168 +0.27948 +0.27927 +0.28407 +0.12822 +0.084005 +0.012004 +0.01754 +0.066084 +0.10824 +0.071328 +0.070013 +0.045027 +0.032209 +0.096907 +0.09168 +0.19842 +0.25724 +0.24863 +0.4 +0.19147 +0.173 +0.20143 +0.19958 +0.27445 +0.21084 +0.21117 +0.22767 +0.28385 +0.2576 +0.25377 +0.2555 +0.17699 +0.16019 +0.15792 +0.17919 +0.23543 +0.24324 +0.28224 +0.30951 +0.21523 +0.14593 +0.15791 +0.22469 +0.18919 +0.30086 +0.29252 +0.21215 +0.25736 +0.17443 +0.17595 +0.1798 +0.1421 +0.063377 +0.29725 +0.27233 +0.29936 +0.29741 +0.30985 +0.31801 +0.28537 +0.28824 +0.27355 +0.25704 +0.34762 +0.080791 +0.1214 +0.094104 +0.13273 +0.073883 +0.082295 +0.061289 +0.0001 +0.06523 +0.098085 +0.1123 +0.21524 +0.12919 +0.24988 +0.21995 +0.079898 +0.18499 +0.22716 +0.19265 +0.22889 +0.21096 +0.20799 +0.19517 +0.29461 +0.28216 +0.27688 +0.24853 +0.18878 +0.23252 +0.15656 +0.19186 +0.24184 +0.23111 +0.28757 +0.31939 +0.19703 +0.11291 +0.16741 +0.21545 +0.2139 +0.2126 +0.27897 +0.223 +0.22273 +0.16283 +0.16509 +0.14625 +0.15182 +0.23864 +0.27647 +0.25224 +0.252 +0.25793 +0.3344 +0.31971 +0.29756 +0.29486 +0.30524 +0.26179 +0.33176 +0.0001 +0.020696 +0.1168 +0.10592 +0.060266 +0.019128 +0.017684 +0.060722 +0.079614 +0.070629 +0.098849 +0.21048 +0.15822 +0.262 +0.20355 +0.22978 +0.17672 +0.25702 +0.2806 +0.24778 +0.23536 +0.20983 +0.21438 +0.22074 +0.29358 +0.25701 +0.25279 +0.20236 +0.20908 +0.143 +0.21081 +0.21936 +0.26224 +0.28729 +0.31045 +0.14693 +0.11361 +0.12804 +0.18595 +0.21142 +0.1081 +0.25913 +0.19897 +0.18372 +0.18032 +0.22073 +0.13767 +0.14011 +0.23226 +0.26374 +0.23351 +0.26364 +0.3402 +0.31918 +0.32584 +0.29474 +0.29435 +0.32296 +0.27031 +0.29744 +0.07639 +0.067639 +0.1067 +0.078687 +0.085448 +0.036031 +0.0001 +0.059555 +0.078754 +0.096521 +0.086022 +0.21088 +0.19864 +0.21781 +0.20603 +0.20415 +0.23062 +0.2107 +0.078956 +0.31742 +0.22687 +0.22765 +0.21188 +0.21379 +0.1581 +0.29004 +0.24432 +0.19901 +0.18524 +0.22079 +0.22849 +0.22048 +0.26565 +0.26657 +0.30802 +0.11466 +0.095852 +0.12872 +0.1405 +0.23019 +0.13755 +0.07328 +0.17854 +0.1463 +0.17843 +0.21501 +0.23081 +0.14766 +0.24764 +0.15792 +0.1748 +0.27462 +0.30007 +0.31503 +0.3373 +0.3344 +0.28293 +0.31479 +0.24021 +0.30152 +0.26486 +0.072521 +0.10548 +0.074254 +0.068433 +0.056307 +0.0001 +0.036687 +0.021201 +0.0357 +0.13118 +0.16998 +0.18474 +0.23824 +0.21081 +0.23969 +0.23253 +0.20002 +0.17332 +0.15484 +0.35479 +0.20429 +0.21543 +0.21158 +0.17208 +0.2254 +0.24535 +0.18881 +0.19575 +0.20133 +0.16159 +0.11641 +0.26078 +0.28726 +0.35346 +0.27023 +0.088274 +0.12752 +0.16896 +0.18691 +0.14458 +0.083355 +0.3404 +0.11446 +0.19179 +0.23264 +0.19727 +0.17946 +0.27431 +0.11407 +0.18227 +0.24691 +0.30578 +0.3276 +0.34397 +0.29989 +0.28737 +0.28777 +0.22236 +0.27605 +0.24808 +0.033039 +0.14852 +0.11737 +0.062543 +0.050796 +0.039055 +0.020766 +0.11406 +0.15853 +0.099994 +0.18589 +0.20488 +0.25525 +0.24619 +0.24837 +0.24548 +0.20242 +0.1911 +0.1484 +0.12154 +0.11492 +0.1962 +0.22228 +0.19047 +0.20649 +0.35734 +0.19432 +0.23062 +0.1752 +0.15043 +0.13936 +0.20487 +0.29276 +0.32592 +0.29667 +0.10812 +0.16719 +0.18391 +0.15644 +0.15883 +0.10816 +0.33383 +0.25923 +0.23611 +0.23828 +0.19131 +0.20316 +0.23386 +0.12641 +0.16876 +0.25263 +0.27365 +0.29314 +0.31678 +0.31068 +0.29115 +0.27475 +0.26789 +0.26013 +0.0001 +0.11941 +0.10654 +0.0001 +0.0001 +0.0001 +0.0001 +0.083213 +0.055197 +0.13856 +0.14887 +0.18323 +0.22066 +0.24967 +0.24593 +0.21705 +0.22992 +0.21817 +0.16546 +0.194 +0.13056 +0.11836 +0.073611 +0.2342 +0.18179 +0.18472 +0.21199 +0.17582 +0.18705 +0.16394 +0.13326 +0.16869 +0.1977 +0.16034 +0.30106 +0.32216 +0.086092 +0.13339 +0.17018 +0.16448 +0.16695 +0.14275 +0.30881 +0.26857 +0.23615 +0.28124 +0.18586 +0.21307 +0.24285 +0.23984 +0.24494 +0.26108 +0.28555 +0.254 +0.32031 +0.29247 +0.26636 +0.29902 +0.29119 +0.097117 +0.08394 +0.081066 +0.055597 +0.075235 +0.0001 +0.0001 +0.0001 +0.044257 +0.063146 +0.113 +0.10458 +0.17194 +0.22852 +0.24313 +0.2123 +0.2178 +0.26289 +0.23865 +0.24905 +0.33819 +0.16889 +0.0922 +0.070207 +0.067865 +0.20736 +0.19083 +0.23974 +0.16545 +0.19099 +0.14802 +0.18362 +0.2044 +0.18532 +0.3163 +0.32349 +0.33107 +0.29757 +0.12477 +0.15222 +0.1876 +0.20532 +0.28568 +0.28682 +0.28496 +0.21852 +0.2586 +0.36635 +0.19934 +0.23087 +0.27458 +0.27435 +0.2756 +0.24843 +0.26018 +0.27515 +0.28701 +0.28391 +0.27453 +0.29684 +0.036273 +0.035065 +0.0001 +0.05485 +0.093792 +0.016438 +0.065881 +0.11004 +0.1115 +0.14094 +0.044499 +0.02085 +0.17976 +0.20247 +0.24778 +0.22263 +0.23667 +0.03458 +0.21278 +0.29495 +0.37146 +0.17252 +0.1893 +0.25109 +0.25948 +0.24883 +0.18281 +0.2 +0.16321 +0.21143 +0.12288 +0.1652 +0.16866 +0.16701 +0.30362 +0.33902 +0.31302 +0.28657 +0.25166 +0.30046 +0.1591 +0.23248 +0.32097 +0.33038 +0.30696 +0.2599 +0.23229 +0.33654 +0.29136 +0.23753 +0.23169 +0.28359 +0.28996 +0.19256 +0.26363 +0.2622 +0.239 +0.25549 +0.0001 +0.015472 +0.045952 +0.045416 +0.0001 +0.066767 +0.070177 +0.052685 +0.065042 +0.074998 +0.14902 +0.0257 +0.070126 +0.040773 +0.18455 +0.23114 +0.22305 +0.23392 +0.25553 +0.25002 +0.2687 +0.15139 +0.16299 +0.15926 +0.18047 +0.23063 +0.23925 +0.25237 +0.20691 +0.18829 +0.17346 +0.2155 +0.13044 +0.16111 +0.192 +0.16435 +0.34937 +0.33379 +0.32067 +0.30204 +0.25934 +0.31387 +0.36777 +0.048142 +0.33104 +0.34217 +0.3146 +0.27925 +0.20682 +0.29661 +0.18395 +0.22139 +0.24429 +0.29001 +0.32848 +0.20769 +0.20501 +0.28013 +0.012246 +0.062176 +0.071009 +0.0001 +0.059509 +0.10218 +0.078849 +0.12899 +0.094953 +0.12071 +0.096578 +0.091524 +0.10919 +0.03272 +0.008325 +0.016611 +0.16657 +0.23421 +0.22432 +0.20928 +0.24555 +0.19407 +0.20955 +0.15564 +0.18107 +0.14004 +0.19451 +0.19079 +0.2393 +0.22491 +0.20633 +0.18989 +0.1528 +0.17607 +0.14524 +0.16172 +0.17924 +0.33825 +0.31589 +0.34815 +0.31172 +0.27528 +0.23454 +0.28055 +0.38893 +0.21909 +0.22162 +0.34145 +0.32405 +0.3109 +0.25614 +0.14215 +0.16624 +0.22732 +0.22565 +0.29809 +0.296 +0.20992 +0.23371 +0.0001 +0.0001 +0.012915 +0.078625 +0.017115 +0.079885 +0.1048 +0.12693 +0.13832 +0.12737 +0.085172 +0.10186 +0.047674 +0.044694 +0.064653 +0.022415 +0.0001 +0.16071 +0.23907 +0.21206 +0.22828 +0.14132 +0.18041 +0.21009 +0.17014 +0.203 +0.18335 +0.14565 +0.23572 +0.20619 +0.22253 +0.19858 +0.18099 +0.13089 +0.20071 +0.14928 +0.14517 +0.23763 +0.15128 +0.30847 +0.3361 +0.33064 +0.23871 +0.23181 +0.27676 +0.34728 +0.22064 +0.2134 +0.18766 +0.3099 +0.30935 +0.18306 +0.20574 +0.18549 +0.23499 +0.26008 +0.27933 +0.25886 +0.065347 +0.076285 +0.014558 +0.01782 +0.032469 +0.096762 +0.080866 +0.051384 +0.058636 +0.099362 +0.11134 +0.13708 +0.069554 +0.090161 +0.11321 +0.088188 +0.1229 +0.091098 +0.086008 +0.1517 +0.21672 +0.20195 +0.23123 +0.17116 +0.19402 +0.19098 +0.24353 +0.26784 +0.37717 +0.3226 +0.22134 +0.21311 +0.20994 +0.19952 +0.21833 +0.11712 +0.1846 +0.17452 +0.16533 +0.3552 +0.32368 +0.31569 +0.29633 +0.31276 +0.21767 +0.22221 +0.31102 +0.21396 +0.23153 +0.24563 +0.28873 +0.21046 +0.22928 +0.16025 +0.22953 +0.18411 +0.22723 +0.26152 +0.27001 +0.17886 +0.12832 +0.058819 +0.05973 +0.025255 +0.032702 +0.058888 +0.049686 +0.008661 +0.061031 +0.085515 +0.13295 +0.096923 +0.052627 +0.10287 +0.10442 +0.11243 +0.093402 +0.13185 +0.036463 +0.16721 +0.22644 +0.19271 +0.28663 +0.19916 +0.18771 +0.19641 +0.20304 +0.25911 +0.33479 +0.29742 +0.23931 +0.21971 +0.20033 +0.19232 +0.33614 +0.37694 +0.28001 +0.15576 +0.17026 +0.34124 +0.32119 +0.33002 +0.30591 +0.27178 +0.19296 +0.067306 +0.072689 +0.23604 +0.26516 +0.22101 +0.19771 +0.23315 +0.23464 +0.10665 +0.19127 +0.19112 +0.21881 +0.069706 +0.08152 +0.085073 +0.094741 +0.084421 +0.11221 +0.1293 +0.087935 +0.071276 +0.053132 +0.053826 +0.008198 +0.006574 +0.053048 +0.11133 +0.10656 +0.18075 +0.1361 +0.076102 +0.1171 +0.094044 +0.061279 +0.17236 +0.24938 +0.15262 +0.15921 +0.18899 +0.1728 +0.18039 +0.21731 +0.26486 +0.33673 +0.33844 +0.24339 +0.19387 +0.23297 +0.25067 +0.35813 +0.1922 +0.17341 +0.13534 +0.26964 +0.32088 +0.30652 +0.3292 +0.31835 +0.076327 +0.099709 +0.20831 +0.046091 +0.24028 +0.2686 +0.14536 +0.18983 +0.24971 +0.22776 +0.089939 +0.16072 +0.26207 +0.084392 +0.085411 +0.072032 +0.077218 +0.026369 +0.06767 +0.11115 +0.14866 +0.096681 +0.072564 +0.013063 +0.011417 +0.03519 +0.063742 +0.027549 +0.10585 +0.080015 +0.10164 +0.13773 +0.11785 +0.16272 +0.11126 +0.005773 +0.20907 +0.26984 +0.15964 +0.16157 +0.18419 +0.15969 +0.18966 +0.20754 +0.25842 +0.29387 +0.20779 +0.2217 +0.24391 +0.23672 +0.27866 +0.19567 +0.18451 +0.18843 +0.27068 +0.25649 +0.29956 +0.26129 +0.22348 +0.12166 +0.015822 +0.1205 +0.094894 +0.055446 +0.2802 +0.2162 +0.17624 +0.15451 +0.24355 +0.24223 +0.21517 +0.22908 +0.27137 +0.0001 +0.039236 +0.047921 +0.066093 +0.060211 +0.043012 +0.088701 +0.057087 +0.1085 +0.039164 +0.075742 +0.10404 +0.015838 +0.083212 +0.091278 +0.11262 +0.059033 +0.15217 +0.13204 +0.073238 +0.10357 +0.027262 +0.016923 +0.21513 +0.19462 +0.13872 +0.15985 +0.17008 +0.16719 +0.18498 +0.21052 +0.24856 +0.20502 +0.1756 +0.21695 +0.19699 +0.25105 +0.18636 +0.15898 +0.18605 +0.20685 +0.28446 +0.23031 +0.27915 +0.1728 +0.047265 +0.064609 +0.012509 +0.085702 +0.059692 +0.072627 +0.27244 +0.19627 +0.17466 +0.18127 +0.21843 +0.27575 +0.2295 +0.22148 +0.27699 +0.22883 +0.021161 +0.028775 +0.080522 +0.058907 +0.050304 +0.15663 +0.079448 +0.13691 +0.088507 +0.033963 +0.036954 +0.040609 +0.014125 +0.084789 +0.079726 +0.021843 +0.092474 +0.11258 +0.092549 +0.041487 +0.015511 +0.008529 +0.23983 +0.1672 +0.17167 +0.16272 +0.15551 +0.17012 +0.19992 +0.19299 +0.2454 +0.17758 +0.16655 +0.16501 +0.20353 +0.24003 +0.19571 +0.26586 +0.20591 +0.1854 +0.17872 +0.22187 +0.18182 +0.14725 +0.067106 +0.051738 +0.019069 +0.027005 +0.30549 +0.33024 +0.23418 +0.2085 +0.20241 +0.17222 +0.21847 +0.27978 +0.21682 +0.19708 +0.24058 +0.23143 +0.2741 +0.007763 +0.12109 +0.18009 +0.042219 +0.08736 +0.10614 +0.15792 +0.054037 +0.040548 +0.10797 +0.0001 +0.079219 +0.0001 +0.11724 +0.043312 +0.10765 +0.13598 +0.071308 +0.006376 +0.0001 +0.043898 +0.26107 +0.19522 +0.17709 +0.14595 +0.13367 +0.17098 +0.21229 +0.14845 +0.20848 +0.17025 +0.12938 +0.20132 +0.14993 +0.23739 +0.21726 +0.27618 +0.23168 +0.33 +0.13701 +0.18617 +0.1484 +0.16047 +0.061062 +0.32973 +0.30915 +0.19236 +0.27819 +0.35443 +0.23411 +0.19088 +0.18535 +0.28338 +0.19822 +0.27857 +0.27344 +0.18483 +0.24961 +0.2136 +0.22519 +0.13071 +0.12021 +0.10858 +0.058363 +0.060307 +0.1127 +0.095618 +0.16402 +0.096579 +0.086765 +0.052234 +0.076626 +0.041742 +0.0001 +0.11221 +0.12171 +0.10991 +0.068758 +0.004681 +0.019622 +0.018476 +0.23624 +0.16928 +0.22073 +0.13776 +0.10247 +0.23975 +0.24378 +0.15199 +0.16711 +0.14923 +0.14511 +0.20695 +0.20903 +0.24015 +0.24932 +0.26253 +0.29183 +0.28476 +0.14818 +0.20606 +0.2184 +0.21667 +0.21276 +0.19737 +0.35514 +0.20621 +0.26337 +0.33858 +0.26478 +0.17712 +0.19647 +0.26317 +0.16131 +0.2234 +0.28936 +0.2626 +0.037921 +0.23672 +0.215 +0.20642 +0.095662 +0.17376 +0.11033 +0.097703 +0.14696 +0.10252 +0.13368 +0.095617 +0.099976 +0.088867 +0.10526 +0.052448 +0.077499 +0.10601 +0.11874 +0.068252 +0.083539 +0.035654 +0.085234 +0.11511 +0.21479 +0.32965 +0.20667 +0.13632 +0.096436 +0.11004 +0.29652 +0.32966 +0.32843 +0.26598 +0.28065 +0.20312 +0.23817 +0.26184 +0.2168 +0.24321 +0.3088 +0.28782 +0.27063 +0.20802 +0.2359 +0.27034 +0.22731 +0.2176 +0.34918 +0.22008 +0.27595 +0.30302 +0.29024 +0.18209 +0.19242 +0.2554 +0.1769 +0.23314 +0.28499 +0.25371 +0.19601 +0.047522 +0.2434 +0.19885 +0.23162 +0.14851 +0.10103 +0.085971 +0.088985 +0.13315 +0.14276 +0.13568 +0.10009 +0.15771 +0.12314 +0.096886 +0.079332 +0.14813 +0.18277 +0.10365 +0.0477 +0.034497 +0.13871 +0.034394 +0.1898 +0.17629 +0.19374 +0.17482 +0.15501 +0.098631 +0.15382 +0.13142 +0.37291 +0.27296 +0.26173 +0.25979 +0.18116 +0.27075 +0.22756 +0.24135 +0.23308 +0.264 +0.29179 +0.18226 +0.24203 +0.24945 +0.22866 +0.21455 +0.31195 +0.23923 +0.25178 +0.28996 +0.29648 +0.29959 +0.1518 +0.25019 +0.18124 +0.25852 +0.27713 +0.19424 +0.16697 +0.14674 +0.077495 +0.22306 +0.24102 +0.23672 +0.057777 +0.064766 +0.049447 +0.15468 +0.071631 +0.018845 +0.028754 +0.088724 +0.12883 +0.10515 +0.080025 +0.09193 +0.053553 +0.074444 +0.070789 +0.04467 +0.027169 +0.032061 +0.19842 +0.24318 +0.21053 +0.18037 +0.14936 +0.064073 +0.13679 +0.27793 +0.36713 +0.25638 +0.24671 +0.23345 +0.1121 +0.23892 +0.20991 +0.23423 +0.24975 +0.29296 +0.21535 +0.24528 +0.22046 +0.2545 +0.23039 +0.21395 +0.030684 +0.27235 +0.25977 +0.28781 +0.29644 +0.017212 +0.17366 +0.24772 +0.18049 +0.27561 +0.26903 +0.21079 +0.1638 +0.21388 +0.11789 +0.12437 +0.24083 +0.25077 +0.2153 +0.0001 +0.0001 +0.12501 +0.066491 +0.0001 +0.0001 +0.053972 +0.11787 +0.13125 +0.043893 +0.097671 +0.06759 +0.03635 +0.12844 +0.066235 +0.06734 +0.054467 +0.23844 +0.19298 +0.26987 +0.19817 +0.12288 +0.062531 +0.13744 +0.12442 +0.27387 +0.25417 +0.20449 +0.21689 +0.14674 +0.16629 +0.19207 +0.22802 +0.26225 +0.31608 +0.24857 +0.25146 +0.24831 +0.15014 +0.22743 +0.2375 +0.0123 +0.053637 +0.10825 +0.02145 +0.10282 +0.074327 +0.1388 +0.23454 +0.16994 +0.29152 +0.27137 +0.18618 +0.13763 +0.21168 +0.22055 +0.10477 +0.067245 +0.24212 +0.22716 +0.29044 +0.01787 +0.11517 +0.046793 +0.0001 +0.031376 +0.038707 +0.18279 +0.17005 +0.085098 +0.051889 +0.0001 +0.017833 +0.055491 +0.052829 +0.027435 +0.00827 +0.19846 +0.22883 +0.3102 +0.1865 +0.11763 +0.072062 +0.12476 +0.15085 +0.28749 +0.24934 +0.24301 +0.23603 +0.15892 +0.13832 +0.1584 +0.10258 +0.24918 +0.33145 +0.38616 +0.3193 +0.25858 +0.11915 +0.16568 +0.21332 +0.24073 +0.060126 +0.083065 +0.087257 +0.096331 +0.097939 +0.14012 +0.22419 +0.31461 +0.27191 +0.26185 +0.18525 +0.15461 +0.17914 +0.1944 +0.089122 +0.041505 +0.21355 +0.2229 +0.30116 +0.21558 +0.031176 +0.087292 +0.079236 +0.023404 +0.124 +0.14605 +0.17625 +0.11058 +0.094061 +0.035211 +0.10714 +0.072961 +0.092538 +0.036031 +0.030659 +0.20867 +0.25125 +0.25089 +0.24805 +0.22469 +0.28306 +0.10424 +0.1686 +0.19631 +0.27534 +0.26735 +0.26992 +0.26708 +0.15876 +0.13608 +0.083012 +0.11027 +0.32152 +0.35579 +0.32001 +0.31071 +0.18493 +0.17761 +0.20013 +0.19637 +0.084338 +0.10673 +0.12199 +0.055108 +0.21877 +0.16335 +0.22928 +0.30162 +0.26496 +0.25979 +0.20092 +0.19134 +0.21911 +0.18639 +0.10986 +0.10046 +0.22542 +0.2457 +0.28638 +0.24438 +0.10571 +0.050681 +0.073807 +0.10694 +0.097329 +0.086505 +0.078838 +0.068901 +0.07425 +0.081644 +0.078978 +0.036191 +0.11216 +0.053396 +0.091471 +0.23045 +0.29088 +0.25165 +0.23049 +0.24159 +0.27833 +0.24701 +0.18254 +0.20756 +0.16719 +0.23919 +0.26612 +0.16554 +0.18151 +0.15245 +0.083726 +0.1266 +0.20407 +0.16715 +0.339 +0.34044 +0.27082 +0.25254 +0.22517 +0.063215 +0.15014 +0.14429 +0.14278 +0.09979 +0.14578 +0.12629 +0.19109 +0.29572 +0.24168 +0.28918 +0.30378 +0.2068 +0.24132 +0.17822 +0.080675 +0.11259 +0.25007 +0.2488 +0.27451 +0.27539 +0.042443 +0.016766 +0.09199 +0.10933 +0.04299 +0.051997 +0.081517 +0.061012 +0.11511 +0.041892 +0.082412 +0.099453 +0.12981 +0.012128 +0.068989 +0.32485 +0.14985 +0.25978 +0.2347 +0.17776 +0.005407 +0.16353 +0.10165 +0.10131 +0.15603 +0.23376 +0.20979 +0.14537 +0.1944 +0.19272 +0.12056 +0.12026 +0.16588 +0.26152 +0.22308 +0.26558 +0.2528 +0.26891 +0.24546 +0.098383 +0.11786 +0.052875 +0.22546 +0.18987 +0.16519 +0.16107 +0.20119 +0.27052 +0.26024 +0.26713 +0.27831 +0.31563 +0.05787 +0.0001 +0.042245 +0.2096 +0.24482 +0.27982 +0.27266 +0.21504 +0.042196 +0.036125 +0.10157 +0.0001 +0.020023 +0.078056 +0.12279 +0.13394 +0.053694 +0.007788 +0.090215 +0.061275 +0.064585 +0.0001 +0.0001 +0.14694 +0.14977 +0.2542 +0.25745 +0.21989 +0.20944 +0.17432 +0.11782 +0.23345 +0.24368 +0.23741 +0.2161 +0.24829 +0.21813 +0.18301 +0.1183 +0.11577 +0.18417 +0.23875 +0.25105 +0.26378 +0.2359 +0.26032 +0.23612 +0.26806 +0.23604 +0.23056 +0.19498 +0.16295 +0.14052 +0.17485 +0.2641 +0.23557 +0.27786 +0.25051 +0.27671 +0.21878 +0.19108 +0.16977 +0.21237 +0.2125 +0.25225 +0.27077 +0.27108 +0.011331 +0.0001 +0.0001 +0.0001 +0.046179 +0.052484 +0.072372 +0.15752 +0.10338 +0.095268 +0.013588 +0.083847 +0.050649 +0.13759 +0.070023 +0.067402 +0.33873 +0.27508 +0.2607 +0.29553 +0.25646 +0.26273 +0.26782 +0.25628 +0.27231 +0.16027 +0.14218 +0.26893 +0.26307 +0.20386 +0.18825 +0.12237 +0.10185 +0.2672 +0.26051 +0.26993 +0.27043 +0.0001 +0.13664 +0.22319 +0.26523 +0.24403 +0.21065 +0.19148 +0.19906 +0.24715 +0.202 +0.24776 +0.26489 +0.23209 +0.26068 +0.26959 +0.22476 +0.20799 +0.15759 +0.24066 +0.27298 +0.24874 +0.24794 +0.12872 +0.062709 +0.084352 +0.043264 +0.09852 +0.076741 +0.062463 +0.068712 +0.093243 +0.061663 +0.085148 +0.076609 +0.11233 +0.048323 +0.072529 +0.16539 +0.15707 +0.30099 +0.28964 +0.27094 +0.30556 +0.23753 +0.24668 +0.2379 +0.14317 +0.20246 +0.1584 +0.15896 +0.25433 +0.19202 +0.199 +0.17445 +0.15568 +0.18923 +0.25772 +0.25446 +0.27848 +0.28162 +0.031034 +0.18374 +0.21393 +0.27504 +0.25679 +0.21149 +0.28835 +0.32013 +0.2262 +0.2109 +0.29169 +0.086238 +0.085654 +0.078285 +0.23638 +0.065071 +0.13879 +0.074616 +0.058438 +0.00348 +0.030991 +0.10174 +0.15367 +0.14641 +0.087964 +0.11511 +0.083472 +0.097552 +0.030787 +0.054675 +0.082358 +0.023924 +0.10771 +0.082451 +0.19674 +0.098007 +0.16547 +0.1199 +0.17162 +0.29746 +0.2734 +0.30625 +0.29319 +0.25631 +0.22481 +0.23537 +0.10553 +0.20286 +0.1791 +0.20422 +0.25128 +0.17163 +0.16992 +0.20044 +0.16368 +0.15079 +0.13951 +0.26923 +0.30593 +0.031542 +0.011508 +0.17647 +0.17379 +0.2703 +0.28549 +0.23953 +0.24522 +0.2575 +0.22947 +0.23037 +0.32314 +0.32196 +0.04638 +0.038076 +0.080399 +0.036712 +0.14148 +0.0954 +0.071028 +0.038938 +0.12932 +0.11566 +0.1236 +0.074663 +0.13689 +0.01827 +0.033008 +0.063636 +0.07047 +0.009419 +0.000392 +0.067813 +0.064963 +0.070211 +0.20137 +0.1259 +0.12492 +0.10998 +0.12104 +0.31329 +0.295 +0.32631 +0.31719 +0.25293 +0.22572 +0.19381 +0.11069 +0.18922 +0.16267 +0.20239 +0.22065 +0.18269 +0.15304 +0.36693 +0.3644 +0.17073 +0.14156 +0.21955 +0.30526 +0.15349 +0.15826 +0.21503 +0.19762 +0.27394 +0.331 +0.22567 +0.2284 +0.25314 +0.2134 +0.23212 +0.31297 +0.10331 +0.097193 +0.070276 +0.098347 +0.11587 +0.11837 +0.064636 +0.083927 +0.1148 +0.15117 +0.078167 +0.0001 +0.044011 +0.10353 +0.10934 +0.08775 +0.076853 +0.084207 +0.032381 +0.0001 +0.10109 +0.070509 +0.052812 +0.090905 +0.11431 +0.11306 +0.077988 +0.11229 +0.26251 +0.30175 +0.32834 +0.27838 +0.23524 +0.22265 +0.16264 +0.1237 +0.17211 +0.17348 +0.17145 +0.23988 +0.19045 +0.19745 +0.15341 +0.34632 +0.18076 +0.13553 +0.20191 +0.29802 +0.31462 +0.19138 +0.21668 +0.23538 +0.25882 +0.28053 +0.27087 +0.2514 +0.28958 +0.28926 +0.29337 +0.28695 +0.12216 +0.11213 +0.085548 +0.11539 +0.087571 +0.12169 +0.067842 +0.052622 +0.066984 +0.095835 +0.077276 +0.069237 +0.12755 +0.15133 +0.12437 +0.097533 +0.091354 +0.12021 +0.02673 +0.063685 +0.092854 +0.083699 +0.053603 +0.13591 +0.10926 +0.062304 +0.1183 +0.19589 +0.29472 +0.28288 +0.27012 +0.26036 +0.22928 +0.23018 +0.21022 +0.16764 +0.18317 +0.22117 +0.17388 +0.21962 +0.19401 +0.19202 +0.17869 +0.35397 +0.32323 +0.1426 +0.14733 +0.10711 +0.15454 +0.16916 +0.19557 +0.19872 +0.21018 +0.24903 +0.23423 +0.26155 +0.27944 +0.31418 +0.28136 +0.098836 +0.10858 +0.093759 +0.078786 +0.077764 +0.076118 +0.088197 +0.023931 +0.1138 +0.044796 +0.13181 +0.10361 +0.14526 +0.081459 +0.097538 +0.11745 +0.048109 +0.080218 +0.11392 +0.10717 +0.082441 +0.078055 +0.026627 +0.069075 +0.096226 +0.04669 +0.084379 +0.14427 +0.11094 +0.25724 +0.27258 +0.28201 +0.23223 +0.23839 +0.23348 +0.22571 +0.1863 +0.19915 +0.23091 +0.22347 +0.1982 +0.19348 +0.19652 +0.22158 +0.19857 +0.32107 +0.15907 +0.14858 +0.11013 +0.097129 +0.19612 +0.23171 +0.2204 +0.2365 +0.26172 +0.26658 +0.24999 +0.25471 +0.32162 +0.05432 +0.051692 +0.045081 +0.069455 +0.12065 +0.085677 +0.0664 +0.028323 +0.071163 +0.040997 +0.11031 +0.10501 +0.072825 +0.037366 +0.11164 +0.18275 +0.14094 +0.11512 +0.095895 +0.11614 +0.13631 +0.11883 +0.038243 +0.075829 +0.0001 +0.03321 +0.077864 +0.092004 +0.090571 +0.088943 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/pres_pvdo.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/pres_pvdo.txt new file mode 100644 index 00000000000..2681766c979 --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/pres_pvdo.txt @@ -0,0 +1,3 @@ +2068000 +5516000 +55160000 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/visc_pvdo.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/visc_pvdo.txt new file mode 100644 index 00000000000..a15f9b49dcf --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/visc_pvdo.txt @@ -0,0 +1,3 @@ +0.00285 +0.00299 +0.003 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/xlin.geos b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/xlin.geos new file mode 100644 index 00000000000..3d99dd84d02 --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/xlin.geos @@ -0,0 +1,60 @@ +3.048 +9.144 +15.24 +21.336 +27.432 +33.528 +39.624 +45.72 +51.816 +57.912 +64.008 +70.104 +76.2 +82.296 +88.392 +94.488 +100.58 +106.68 +112.78 +118.87 +124.97 +131.06 +137.16 +143.26 +149.35 +155.45 +161.54 +167.64 +173.74 +179.83 +185.93 +192.02 +198.12 +204.22 +210.31 +216.41 +222.5 +228.6 +234.7 +240.79 +246.89 +252.98 +259.08 +265.18 +271.27 +277.37 +283.46 +289.56 +295.66 +301.75 +307.85 +313.94 +320.04 +326.14 +332.23 +338.33 +344.42 +350.52 +356.62 +362.71 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/ylin.geos b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/ylin.geos new file mode 100644 index 00000000000..99a6fec4924 --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/ylin.geos @@ -0,0 +1,220 @@ +1.524 +4.572 +7.62 +10.668 +13.716 +16.764 +19.812 +22.86 +25.908 +28.956 +32.004 +35.052 +38.1 +41.148 +44.196 +47.244 +50.292 +53.34 +56.388 +59.436 +62.484 +65.532 +68.58 +71.628 +74.676 +77.724 +80.772 +83.82 +86.868 +89.916 +92.964 +96.012 +99.06 +102.11 +105.16 +108.2 +111.25 +114.3 +117.35 +120.4 +123.44 +126.49 +129.54 +132.59 +135.64 +138.68 +141.73 +144.78 +147.83 +150.88 +153.92 +156.97 +160.02 +163.07 +166.12 +169.16 +172.21 +175.26 +178.31 +181.36 +184.4 +187.45 +190.5 +193.55 +196.6 +199.64 +202.69 +205.74 +208.79 +211.84 +214.88 +217.93 +220.98 +224.03 +227.08 +230.12 +233.17 +236.22 +239.27 +242.32 +245.36 +248.41 +251.46 +254.51 +257.56 +260.6 +263.65 +266.7 +269.75 +272.8 +275.84 +278.89 +281.94 +284.99 +288.04 +291.08 +294.13 +297.18 +300.23 +303.28 +306.32 +309.37 +312.42 +315.47 +318.52 +321.56 +324.61 +327.66 +330.71 +333.76 +336.8 +339.85 +342.9 +345.95 +349 +352.04 +355.09 +358.14 +361.19 +364.24 +367.28 +370.33 +373.38 +376.43 +379.48 +382.52 +385.57 +388.62 +391.67 +394.72 +397.76 +400.81 +403.86 +406.91 +409.96 +413 +416.05 +419.1 +422.15 +425.2 +428.24 +431.29 +434.34 +437.39 +440.44 +443.48 +446.53 +449.58 +452.63 +455.68 +458.72 +461.77 +464.82 +467.87 +470.92 +473.96 +477.01 +480.06 +483.11 +486.16 +489.2 +492.25 +495.3 +498.35 +501.4 +504.44 +507.49 +510.54 +513.59 +516.64 +519.68 +522.73 +525.78 +528.83 +531.88 +534.92 +537.97 +541.02 +544.07 +547.12 +550.16 +553.21 +556.26 +559.31 +562.36 +565.4 +568.45 +571.5 +574.55 +577.6 +580.64 +583.69 +586.74 +589.79 +592.84 +595.88 +598.93 +601.98 +605.03 +608.08 +611.12 +614.17 +617.22 +620.27 +623.32 +626.36 +629.41 +632.46 +635.51 +638.56 +641.6 +644.65 +647.7 +650.75 +653.8 +656.84 +659.89 +662.94 +665.99 +669.04 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/zlin.geos b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/zlin.geos new file mode 100644 index 00000000000..63ff1592a67 --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/zlin.geos @@ -0,0 +1 @@ +0.3048 diff --git a/src/coreComponents/linearAlgebra/interfaces/hypre/mgrStrategies/ImmiscibleMultiphaseFVM.hpp b/src/coreComponents/linearAlgebra/interfaces/hypre/mgrStrategies/ImmiscibleMultiphaseFVM.hpp index 1fe5b33f15d..3f05ac5987a 100644 --- a/src/coreComponents/linearAlgebra/interfaces/hypre/mgrStrategies/ImmiscibleMultiphaseFVM.hpp +++ b/src/coreComponents/linearAlgebra/interfaces/hypre/mgrStrategies/ImmiscibleMultiphaseFVM.hpp @@ -58,7 +58,7 @@ class ImmiscibleMultiphaseFVM : public MGRStrategyBase< 1 > // Level 0: eliminate last density which corresponds to the volume constraint equation // m_labels[0].resize( m_numBlocks - 1 ); // std::iota( m_labels[0].begin(), m_labels[0].end(), 0 ); - + // Level 0: eliminate the phase volume fractions m_labels[0].push_back( 0 ); From 3e698b84f77bae87eeb1121b0f555716f1592b7e Mon Sep 17 00:00:00 2001 From: DENEL Bertrand Date: Wed, 30 Oct 2024 18:42:46 -0500 Subject: [PATCH 055/102] Created an ats test from the gravitySegration example. --- ...mmiscibleTwoPhase_GravitySegregation_1d.ats | 18 ++++++++++++++++++ ...mmiscibleTwoPhase_GravitySegregation_1d.xml | 10 +++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_GravitySegregation_1d/immiscibleTwoPhase_GravitySegregation_1d.ats diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_GravitySegregation_1d/immiscibleTwoPhase_GravitySegregation_1d.ats b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_GravitySegregation_1d/immiscibleTwoPhase_GravitySegregation_1d.ats new file mode 100644 index 00000000000..b7f470b932f --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_GravitySegregation_1d/immiscibleTwoPhase_GravitySegregation_1d.ats @@ -0,0 +1,18 @@ +from geos.ats.test_builder import TestDeck, RestartcheckParameters, generate_geos_tests + +restartcheck_params = {} +restartcheck_params['atol'] = 1.0E-8 +restartcheck_params['rtol'] = 1.0E-8 + +decks = [ + TestDeck( + name="immiscibleTwoPhase_GravitySegregation_1d", + description= + 'Test that 2 fluids can be seperated based on gravity.', + partitions=((1, 1, 1), ), + restart_step=0, + check_step=45, + restartcheck_params=RestartcheckParameters(**restartcheck_params)) +] + +generate_geos_tests(decks) diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_GravitySegregation_1d/immiscibleTwoPhase_GravitySegregation_1d.xml b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_GravitySegregation_1d/immiscibleTwoPhase_GravitySegregation_1d.xml index b4390686079..12e6d52f990 100644 --- a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_GravitySegregation_1d/immiscibleTwoPhase_GravitySegregation_1d.xml +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_GravitySegregation_1d/immiscibleTwoPhase_GravitySegregation_1d.xml @@ -49,6 +49,12 @@ + + @@ -128,7 +134,7 @@ name="rockPorosity" defaultReferencePorosity="1.0" referencePressure="0.0" - compressibility="0.0" /> + compressibility="1e-9" /> + From 98cbe14a81ae3875e5ec6ffa303c1a9d8df6f867 Mon Sep 17 00:00:00 2001 From: DENEL Bertrand Date: Thu, 31 Oct 2024 11:50:39 -0500 Subject: [PATCH 056/102] Updated integrated test ID after first dry run. --- .integrated_tests.yaml | 2 +- BASELINE_NOTES.md | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.integrated_tests.yaml b/.integrated_tests.yaml index 2d289765a28..0d6d65574d0 100644 --- a/.integrated_tests.yaml +++ b/.integrated_tests.yaml @@ -1,6 +1,6 @@ baselines: bucket: geosx - baseline: integratedTests/baseline_integratedTests-pr2878-8188-ed2ded2 + baseline: integratedTests/baseline_integratedTests-pr3251-8367-3e698b8 allow_fail: all: '' diff --git a/BASELINE_NOTES.md b/BASELINE_NOTES.md index 65cd8d82bd9..dddfe377cc9 100644 --- a/BASELINE_NOTES.md +++ b/BASELINE_NOTES.md @@ -6,6 +6,10 @@ This file is designed to track changes to the integrated test baselines. Any developer who updates the baseline ID in the .integrated_tests.yaml file is expected to create an entry in this file with the pull request number, date, and their justification for rebaselining. These notes should be in reverse-chronological order, and use the following time format: (YYYY-MM-DD). +PR #3251 (2024-10-31) +===================== +Added tests for the brand new Immiscible Multiphase solver. + PR #2878 (2024-10-17) ===================== Sorted region cellBlocks names alphabetically. Therefore affected ordering of: faceManager/elemSubRegionList, nodeManager/elemList, nodeManager/elemSubRegionList, SurfaceElementSubRegion::fractureElementsToCellSubRegions, field::perforation::reservoirElementSubregion. From 90e8db37aa83816a83dd373552a58c52c13a219e Mon Sep 17 00:00:00 2001 From: DENEL Bertrand Date: Thu, 31 Oct 2024 16:51:08 -0500 Subject: [PATCH 057/102] Added more ats. --- .../immiscibleTwoPhase_CapillaryPressure.ats | 18 ++++++++++++++++++ .../immiscibleTwoPhase_SPE10_layer84.ats | 18 ++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_CapillaryPressure/immiscibleTwoPhase_CapillaryPressure.ats create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/immiscibleTwoPhase_SPE10_layer84.ats diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_CapillaryPressure/immiscibleTwoPhase_CapillaryPressure.ats b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_CapillaryPressure/immiscibleTwoPhase_CapillaryPressure.ats new file mode 100644 index 00000000000..8d26b61945c --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_CapillaryPressure/immiscibleTwoPhase_CapillaryPressure.ats @@ -0,0 +1,18 @@ +from geos.ats.test_builder import TestDeck, RestartcheckParameters, generate_geos_tests + +restartcheck_params = {} +restartcheck_params['atol'] = 1.0E-8 +restartcheck_params['rtol'] = 1.0E-8 + +decks = [ + TestDeck( + name="immiscibleTwoPhase_CapillaryPressure", + description= + 'Test 2 fluids can mix based on capillary pressure.', + partitions=((1, 1, 1), ), + restart_step=0, + check_step=68, + restartcheck_params=RestartcheckParameters(**restartcheck_params)) +] + +generate_geos_tests(decks) diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/immiscibleTwoPhase_SPE10_layer84.ats b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/immiscibleTwoPhase_SPE10_layer84.ats new file mode 100644 index 00000000000..f45175016bd --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/immiscibleTwoPhase_SPE10_layer84.ats @@ -0,0 +1,18 @@ +from geos.ats.test_builder import TestDeck, RestartcheckParameters, generate_geos_tests + +restartcheck_params = {} +restartcheck_params['atol'] = 1.0E-8 +restartcheck_params['rtol'] = 1.0E-8 + +decks = [ + TestDeck( + name="immiscibleTwoPhase_SPE10_layer84_benchmark_iterative.xml", + description= + 'Two phase immiscible flow on SPE10 layer84 using iterative solver.', + partitions=((1, 1, 1), ), + restart_step=0, + check_step=89, + restartcheck_params=RestartcheckParameters(**restartcheck_params)) +] + +generate_geos_tests(decks) From fd702fc552ff4f105b3e18f471951a33b04c31a8 Mon Sep 17 00:00:00 2001 From: DENEL Bertrand Date: Thu, 31 Oct 2024 16:58:22 -0500 Subject: [PATCH 058/102] Added more ats, part2. --- .../immiscibleTwoPhase_CapillaryPressure.xml | 10 +++++++++- ...immiscibleTwoPhase_SPE10_layer84_base_iterative.xml | 8 ++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_CapillaryPressure/immiscibleTwoPhase_CapillaryPressure.xml b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_CapillaryPressure/immiscibleTwoPhase_CapillaryPressure.xml index 46d250ee052..64169b10c0b 100644 --- a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_CapillaryPressure/immiscibleTwoPhase_CapillaryPressure.xml +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_CapillaryPressure/immiscibleTwoPhase_CapillaryPressure.xml @@ -49,6 +49,12 @@ + + @@ -186,5 +192,7 @@ + - \ No newline at end of file + diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/immiscibleTwoPhase_SPE10_layer84_base_iterative.xml b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/immiscibleTwoPhase_SPE10_layer84_base_iterative.xml index 13264fe80d0..f42872756a0 100644 --- a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/immiscibleTwoPhase_SPE10_layer84_base_iterative.xml +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_SPE10_layer84/immiscibleTwoPhase_SPE10_layer84_base_iterative.xml @@ -34,6 +34,12 @@ name="solverApplications" maxEventDt="1e6" target="/Solvers/FlowSolver"/> + + @@ -233,6 +239,8 @@ + From 41c19e10744657e0e6671379349c3268454d68c8 Mon Sep 17 00:00:00 2001 From: DENEL Bertrand Date: Mon, 4 Nov 2024 22:14:21 -0600 Subject: [PATCH 059/102] Fixed capillaryPressure test. --- .../immiscibleTwoPhase_CapillaryPressure.xml | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_CapillaryPressure/immiscibleTwoPhase_CapillaryPressure.xml b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_CapillaryPressure/immiscibleTwoPhase_CapillaryPressure.xml index 64169b10c0b..8b2c07ec180 100644 --- a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_CapillaryPressure/immiscibleTwoPhase_CapillaryPressure.xml +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_CapillaryPressure/immiscibleTwoPhase_CapillaryPressure.xml @@ -32,13 +32,6 @@ cellBlockNames="{ block1 }" /> - - - - + compressibility="1e-12" /> - From ff37803dabfddcc85c75928491abdbfa31dbdd32 Mon Sep 17 00:00:00 2001 From: DENEL Bertrand Date: Wed, 6 Nov 2024 16:38:11 -0600 Subject: [PATCH 060/102] Removed unused function. --- .../fluidFlow/ImmiscibleMultiphaseFlow.cpp | 62 ------------------- 1 file changed, 62 deletions(-) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp index f5dfe772a65..e14deff1295 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp @@ -784,68 +784,6 @@ char const bcLogMessage[] = } -void applyAndSpecifyFieldValue( real64 const & time_n, - real64 const & dt, - MeshLevel & mesh, - globalIndex const rankOffset, - string const dofKey, - bool const, - integer const idof, - string const fieldKey, - string const boundaryFieldKey, - CRSMatrixView< real64, globalIndex const > const & localMatrix, - arrayView1d< real64 > const & localRhs ) -{ - FieldSpecificationManager & fsManager = FieldSpecificationManager::getInstance(); - - fsManager.apply< ElementSubRegionBase >( time_n + dt, - mesh, - fieldKey, - [&]( FieldSpecificationBase const & fs, - string const &, - SortedArrayView< localIndex const > const & lset, - ElementSubRegionBase & subRegion, - string const & ) - { - // Specify the bc value of the field - fs.applyFieldValue< FieldSpecificationEqual, - parallelDevicePolicy<> >( lset, - time_n + dt, - subRegion, - boundaryFieldKey ); - - arrayView1d< integer const > const ghostRank = subRegion.ghostRank(); - arrayView1d< globalIndex const > const dofNumber = - subRegion.getReference< array1d< globalIndex > >( dofKey ); - arrayView1d< real64 const > const bcField = - subRegion.getReference< array1d< real64 > >( boundaryFieldKey ); - arrayView1d< real64 const > const field = - subRegion.getReference< array1d< real64 > >( fieldKey ); - - forAll< parallelDevicePolicy<> >( lset.size(), [=] GEOS_HOST_DEVICE ( localIndex const a ) - { - localIndex const ei = lset[a]; - if( ghostRank[ei] >= 0 ) - { - return; - } - - globalIndex const dofIndex = dofNumber[ei]; - localIndex const localRow = dofIndex - rankOffset; - real64 rhsValue; - - // Apply field value to the matrix/rhs - FieldSpecificationEqual::SpecifyFieldValue( dofIndex + idof, - rankOffset, - localMatrix, - rhsValue, - bcField[ei], - field[ei] ); - localRhs[localRow + idof] = rhsValue; - } ); - } ); -} - void ImmiscibleMultiphaseFlow::applyDirichletBC( real64 const time_n, real64 const dt, DofManager const & dofManager, From 4453d20fb118b9013490b98b65c7c8a723e04a82 Mon Sep 17 00:00:00 2001 From: DENEL Bertrand Date: Fri, 8 Nov 2024 12:08:52 -0600 Subject: [PATCH 061/102] Added documentation for the two-phase fluid model. --- .../constitutive/docs/FluidModels.rst | 2 + .../constitutive/docs/TwoPhaseFluid.rst | 89 +++++++++++++++++++ .../fluid/twophasefluid/TwoPhaseFluid.cpp | 4 +- 3 files changed, 93 insertions(+), 2 deletions(-) create mode 100644 src/coreComponents/constitutive/docs/TwoPhaseFluid.rst diff --git a/src/coreComponents/constitutive/docs/FluidModels.rst b/src/coreComponents/constitutive/docs/FluidModels.rst index 445f8a82f0b..741a8426e2b 100644 --- a/src/coreComponents/constitutive/docs/FluidModels.rst +++ b/src/coreComponents/constitutive/docs/FluidModels.rst @@ -11,6 +11,8 @@ single fluids and fluid mixtures. CompressibleSinglePhaseFluid + TwoPhaseFluid + BlackOilFluid CompositionalMultiphaseFluid diff --git a/src/coreComponents/constitutive/docs/TwoPhaseFluid.rst b/src/coreComponents/constitutive/docs/TwoPhaseFluid.rst new file mode 100644 index 00000000000..d5e3bd52c51 --- /dev/null +++ b/src/coreComponents/constitutive/docs/TwoPhaseFluid.rst @@ -0,0 +1,89 @@ +.. _TwoPhaseFluid: + +############################################ +Two-phase fluid model +############################################ + +Overview +========================= + +This model represents a two-phase fluid with pressure-dependent density and viscosity. + +For each phase, both density and viscosity are described as tabulated data, either in the form of ``TableFunction`` or text files. + +In the case of text files, one file is expected per phase and should consist of three columns: pressure, density and viscosity. + +Note that currently, there is no temperature dependence in the model. + + +Parameters +========================= + +The model is represented by ```` node in the input. + +The following attributes are supported: + +.. include:: /docs/sphinx/datastructure/TwoPhaseFluid.rst + + +Example using TableFunctions +============================ + +.. code-block:: xml + + + + + + + + + + + + + + + + +Example using text files +========================= + +.. code-block:: xml + + + + + + +with, for example, ``water.txt`` being set as: + +.. code-block:: text + # P(Pa) Dens(kg/m3) Visc(Pa.s) + 2068000 980.683 0.0003 + 5516000 982.07 0.0003 + 30600000 992.233 0.0003 + 55160000 1002.265 0.0003 diff --git a/src/coreComponents/constitutive/fluid/twophasefluid/TwoPhaseFluid.cpp b/src/coreComponents/constitutive/fluid/twophasefluid/TwoPhaseFluid.cpp index 208fe448e35..b0fc13116fa 100644 --- a/src/coreComponents/constitutive/fluid/twophasefluid/TwoPhaseFluid.cpp +++ b/src/coreComponents/constitutive/fluid/twophasefluid/TwoPhaseFluid.cpp @@ -51,13 +51,13 @@ TwoPhaseFluid::TwoPhaseFluid( string const & name, Group * const parent ) setRTTypeName( rtTypes::CustomTypes::groupNameRefArray ). setInputFlag( InputFlags::OPTIONAL ). setDescription( "List of density TableFuncion names from the Function block. \n" - "The user must provide one TableFunction par phase, respecting the order provided in \"phaseNames\"." ); + "The user must provide one TableFunction per phase, respecting the order provided in \"phaseNames\"." ); registerWrapper( viewKeyStruct::viscosityTableNamesString(), &m_viscosityTableNames ). setRTTypeName( rtTypes::CustomTypes::groupNameRefArray ). setInputFlag( InputFlags::OPTIONAL ). setDescription( "List of viscosity TableFuncion names from the Function block. \n" - "The user must provide one TableFunction par phase, respecting the order provided in \"phaseNames\"." ); + "The user must provide one TableFunction per phase, respecting the order provided in \"phaseNames\"." ); registerField( fields::twophasefluid::phaseDensity{}, &m_phaseDensity.value ); registerField( fields::twophasefluid::dPhaseDensity{}, &m_phaseDensity.derivs ); From 316b4b77b4405a00807d676a4b7327962460d69c Mon Sep 17 00:00:00 2001 From: DENEL Bertrand Date: Fri, 8 Nov 2024 15:38:56 -0600 Subject: [PATCH 062/102] Fixed doc. --- src/coreComponents/constitutive/docs/TwoPhaseFluid.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/coreComponents/constitutive/docs/TwoPhaseFluid.rst b/src/coreComponents/constitutive/docs/TwoPhaseFluid.rst index d5e3bd52c51..39b35510c63 100644 --- a/src/coreComponents/constitutive/docs/TwoPhaseFluid.rst +++ b/src/coreComponents/constitutive/docs/TwoPhaseFluid.rst @@ -24,7 +24,7 @@ The model is represented by ```` node in the input. The following attributes are supported: .. include:: /docs/sphinx/datastructure/TwoPhaseFluid.rst - + Example using TableFunctions ============================ @@ -82,6 +82,7 @@ Example using text files with, for example, ``water.txt`` being set as: .. code-block:: text + # P(Pa) Dens(kg/m3) Visc(Pa.s) 2068000 980.683 0.0003 5516000 982.07 0.0003 From 389bfb0ac5a2345ef8780dffc168f2b76d6215bd Mon Sep 17 00:00:00 2001 From: rpiazza87 Date: Mon, 11 Nov 2024 16:19:24 -0800 Subject: [PATCH 063/102] included total mass formulation --- .../fluidFlow/ImmiscibleMultiphaseFlow.cpp | 26 ++++++++++++++----- .../fluidFlow/ImmiscibleMultiphaseFlow.hpp | 1 + .../fluidFlow/ImmiscibleMultiphaseKernels.hpp | 24 ++++++++++++++--- 3 files changed, 41 insertions(+), 10 deletions(-) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp index e14deff1295..e08a92f69c1 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp @@ -24,8 +24,8 @@ #include "physicsSolvers/fluidFlow/ImmiscibleMultiphaseKernels.hpp" #include "physicsSolvers/SolverBaseKernels.hpp" -#include "physicsSolvers/fluidFlow/IsothermalCompositionalMultiphaseBaseKernels.hpp" // should be removed eventually -//#include "physicsSolvers/fluidFlow/IsothermalCompositionalMultiphaseFVMKernels.hpp" +#include "physicsSolvers/fluidFlow/IsothermalCompositionalMultiphaseBaseKernels.hpp" +#include "physicsSolvers/fluidFlow/CompositionalMultiphaseUtilities.hpp" #include "constitutive/ConstitutiveManager.hpp" #include "constitutive/capillaryPressure/CapillaryPressureFields.hpp" @@ -34,9 +34,7 @@ #include "fieldSpecification/SourceFluxBoundaryCondition.hpp" - #include "constitutive/ConstitutivePassThru.hpp" - #include "constitutive/fluid/twophasefluid/TwoPhaseFluid.hpp" #include @@ -60,11 +58,17 @@ ImmiscibleMultiphaseFlow::ImmiscibleMultiphaseFlow( const string & name, FlowSolverBase( name, parent ), m_numPhases( 2 ), m_hasCapPressure( 0 ), - m_useTotalMassEquation ( 0 ) + m_useTotalMassEquation ( 1 ) { this->registerWrapper( viewKeyStruct::inputTemperatureString(), &m_inputTemperature ). setInputFlag( InputFlags::REQUIRED ). setDescription( "Temperature" ); + + this->registerWrapper( viewKeyStruct::useTotalMassEquationString(), &m_useTotalMassEquation ). + setSizedFromParent( 0 ). + setInputFlag( InputFlags::OPTIONAL ). + setApplyDefaultValue( 1 ). + setDescription( "Flag indicating whether total mass equation is used" ); } void ImmiscibleMultiphaseFlow::postInputInitialization() @@ -671,6 +675,16 @@ void ImmiscibleMultiphaseFlow::assembleAccumulationTerm( DomainPartition & domai // complete + using namespace compositionalMultiphaseUtilities; + + if( m_useTotalMassEquation ) + { + // apply equation/variable change transformation to the component mass balance equations + real64 work[numofPhases]{}; + shiftRowsAheadByOneAndReplaceFirstRowWithColumnSum( numofPhases, numofPhases, localJacobian, work ); + shiftElementsAheadByOneAndReplaceFirstElementWithSum( numofPhases, localResidual ); + } + integer const numRows = numofPhases; for( integer i = 0; i < numRows; ++i ) @@ -998,7 +1012,7 @@ void ImmiscibleMultiphaseFlow::applySourceFluxBC( real64 const time, real64 const sizeScalingFactor = bcAllSetsSize[bcNameToBcId.at( fs.getName())]; integer const fluidPhaseId = fs.getComponent(); integer const numFluidPhases = m_numPhases; - integer useTotalMassEquation = 0; + integer useTotalMassEquation = m_useTotalMassEquation; forAll< parallelDevicePolicy<> >( targetSet.size(), [sizeScalingFactor, targetSet, rankOffset, diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp index 565a2b1a562..d393df265c0 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp @@ -220,6 +220,7 @@ class ImmiscibleMultiphaseFlow : public FlowSolverBase static constexpr char const * capPressureNamesString() { return "capPressureNames"; } static constexpr char const * relPermNamesString() { return "relPermNames"; } static constexpr char const * elemDofFieldString() { return "elemDofField"; } + static constexpr char const * useTotalMassEquationString() { return "useTotalMassEquation"; } }; diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseKernels.hpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseKernels.hpp index 0f668592462..27f2bc65d8f 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseKernels.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseKernels.hpp @@ -39,7 +39,7 @@ #include "linearAlgebra/interfaces/InterfaceTypes.hpp" #include "physicsSolvers/fluidFlow/FlowSolverBaseFields.hpp" #include "physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlowFields.hpp" -//#include "physicsSolvers/fluidFlow/SinglePhaseBaseKernels.hpp" // check need of multiphase equivalent +#include "physicsSolvers/fluidFlow/CompositionalMultiphaseUtilities.hpp" #include "physicsSolvers/fluidFlow/StencilAccessors.hpp" #include "physicsSolvers/SolverBaseKernels.hpp" @@ -101,11 +101,14 @@ class FaceBasedAssemblyKernelBase * @param[in] rankOffset the offset of my MPI rank * @param[in] dofNumberAccessor accessor for the dof numbers * @param[in] multiPhaseFlowAccessors accessor for wrappers registered by the solver + * @param[in] fluidAccessors accessor for wrappers registered by the fluid model * @param[in] capPressureAccessors accessor for wrappers registered by the capillary pressure model * @param[in] permeabilityAccessors accessor for wrappers registered by the permeability model * @param[in] dt time step size * @param[inout] localMatrix the local CRS matrix * @param[inout] localRhs the local right-hand side vector + * @param[inout] hasCapPressure flag to indicate whether problem includes capillarity + * @param[inout] useTotalMassEquation flag to indicate whether to use the total mass formulation */ FaceBasedAssemblyKernelBase( integer const numPhases, globalIndex const rankOffset, @@ -138,7 +141,7 @@ class FaceBasedAssemblyKernelBase m_localRhs( localRhs ), m_hasCapPressure ( hasCapPressure ), m_useTotalMassEquation ( useTotalMassEquation ) - {GEOS_UNUSED_VAR( m_useTotalMassEquation );} + {} protected: @@ -220,11 +223,12 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase /** * @brief Constructor for the kernel interface + * @param[in] numPhases number of fluid phases * @param[in] rankOffset the offset of my MPI rank * @param[in] stencilWrapper reference to the stencil wrapper * @param[in] dofNumberAccessor - * @param[in] singlePhaseFlowAccessors - * @param[in] singlePhaseFluidAccessors + * @param[in] multiPhaseFlowAccessors + * @param[in] fluidAccessors * @param[in] capPressureAccessors * @param[in] permeabilityAccessors * @param[in] dt time step size @@ -620,6 +624,18 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase StackVariables & stack, FUNC && kernelOp = NoOpFunc{} ) const { + using namespace compositionalMultiphaseUtilities; + + if( m_useTotalMassEquation ) + { + // Apply equation/variable change transformation(s) + stackArray1d< real64, maxStencilSize * numDof > work( stack.stencilSize * numDof ); + shiftBlockRowsAheadByOneAndReplaceFirstRowWithColumnSum( m_numPhases, numEqn, numDof * stack.stencilSize, stack.numFluxElems, + stack.localFluxJacobian, work ); + shiftBlockElementsAheadByOneAndReplaceFirstElementWithSum( m_numPhases, numEqn, stack.numFluxElems, + stack.localFlux ); + } + // add contribution to residual and jacobian into: // - the mass balance equation // note that numDof includes derivatives wrt temperature if this class is derived in ThermalKernels From 73dc82f7e2ee1dc0d6c8476abd0f5803c3a67857 Mon Sep 17 00:00:00 2001 From: Ammara-14 Date: Mon, 18 Nov 2024 11:52:20 -0800 Subject: [PATCH 064/102] updated the assembleAccumulationTerm kernel and added documentation for the immiscible multiphase solver --- .../fluidFlow/ImmiscibleMultiphaseFlow.cpp | 106 +----- .../docs/ImmiscibleMultiphaseFlow.rst | 206 +++++++++++ .../ImmiscibleMultiphaseKernels.hpp | 325 ++++++++++++++++++ 3 files changed, 543 insertions(+), 94 deletions(-) create mode 100644 src/coreComponents/physicsSolvers/fluidFlow/docs/ImmiscibleMultiphaseFlow.rst diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp index 506d4f21382..7270185f06f 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp @@ -602,100 +602,18 @@ void ImmiscibleMultiphaseFlow::assembleAccumulationTerm( DomainPartition & domai TwoPhaseFluid const & fluid = getConstitutiveModel< TwoPhaseFluid >( subRegion, fluidName ); CoupledSolidBase const & solid = getConstitutiveModel< CoupledSolidBase >( subRegion, solidName ); - //arrayView1d< real64 const > const pres = subRegion.getField< fields::flow::pressure >(); - integer const numofPhases = 2; - globalIndex const rankOffset = dofManager.rankOffset(); - arrayView1d< globalIndex const > const dofNumber = subRegion.getReference< array1d< globalIndex > >( dofKey ); - arrayView1d< integer const > const elemGhostRank= subRegion.ghostRank(); - arrayView1d< real64 const > const volume = subRegion.getElementVolume(); - arrayView2d< real64 const > const porosity = solid.getPorosity(); - arrayView2d< real64 const > const dPoro_dPres = solid.getDporosity_dPressure(); - arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFrac= subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); - arrayView3d< real64 const, multifluid::USD_PHASE > phaseDens = fluid.phaseDensity(); - arrayView4d< real64 const, multifluid::USD_PHASE_DC > dPhaseDens = fluid.dPhaseDensity(); - arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const PhaseMass_n = subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseMass_n >(); - - // The line below is to be used if we want to use the total mass flux formulation - //BitFlags< ElementBasedAssemblyKernelFlags > m_kernelFlags = kernelFlags; - - - integer const numElems = subRegion.size(); - forAll< parallelDevicePolicy<> >( - numElems, [=] GEOS_HOST_DEVICE ( localIndex const ei ) - { - if( elemGhostRank( ei ) >= 0 ) - { - return; - } - - // setup - globalIndex dofIndices[2]{}; - real64 localResidual[2]{}; - real64 localJacobian[2][2]{}; - - real64 const poreVolume = volume[ei] * porosity[ei][0]; - real64 const dPoreVolume_dPres = volume[ei] * dPoro_dPres[ei][0]; - - localIndex localRow = dofNumber[ei] - rankOffset; - - for( integer idof = 0; idof < 2; ++idof ) - { - dofIndices[idof] = dofNumber[ei] + idof; - } - - // compute accumulation - int signPotDiff[2] = {1, -1}; - - for( integer ip = 0; ip < numofPhases; ++ip ) - { - real64 const phaseMass = poreVolume * phaseVolFrac[ei][ip] * phaseDens[ei][0][ip]; - real64 const phaseMass_n = PhaseMass_n[ei][ip]; - - localResidual[ip] += phaseMass - phaseMass_n; - - real64 const dPhaseMass_dP = dPoreVolume_dPres * phaseVolFrac[ei][ip] * phaseDens[ei][0][ip] - + poreVolume * phaseVolFrac[ei][ip] * dPhaseDens[ei][0][ip][0]; - localJacobian[ip][0] += dPhaseMass_dP; - - real64 const dPhaseMass_dS = poreVolume * phaseDens[ei][0][ip]; - - - // if ( ip == 0) - // { - // localJacobian[ip][1] += dPhaseMass_dS; - // } else { - // localJacobian[ip][1] -= dPhaseMass_dS; - // } - - localJacobian[ip][1] += signPotDiff[ip] * dPhaseMass_dS; - - } - - // complete - - using namespace compositionalMultiphaseUtilities; - - if( m_useTotalMassEquation ) - { - // apply equation/variable change transformation to the component mass balance equations - real64 work[numofPhases]{}; - shiftRowsAheadByOneAndReplaceFirstRowWithColumnSum( numofPhases, numofPhases, localJacobian, work ); - shiftElementsAheadByOneAndReplaceFirstElementWithSum( numofPhases, localResidual ); - } - - integer const numRows = numofPhases; - - for( integer i = 0; i < numRows; ++i ) - { - localRhs[localRow + i] += localResidual[i]; - localMatrix.addToRow< serialAtomic >( localRow + i, - dofIndices, - localJacobian[i], - 2 ); - } - - } ); - + immiscibleMultiphaseKernels:: + AccumulationKernelFactory:: + createAndLaunch< parallelDevicePolicy<> >( m_numPhases, + dofManager.rankOffset(), + m_useTotalMassEquation, + dofKey, + subRegion, + fluid, + solid, + localMatrix, + localRhs ); + } ); } ); diff --git a/src/coreComponents/physicsSolvers/fluidFlow/docs/ImmiscibleMultiphaseFlow.rst b/src/coreComponents/physicsSolvers/fluidFlow/docs/ImmiscibleMultiphaseFlow.rst new file mode 100644 index 00000000000..b7e98af3c76 --- /dev/null +++ b/src/coreComponents/physicsSolvers/fluidFlow/docs/ImmiscibleMultiphaseFlow.rst @@ -0,0 +1,206 @@ +.. _ImmiscibleMultiphaseFlow: + +####################################### +Immiscible Multiphase Flow Solver +####################################### + +Introduction +============= + +This flow solver is used to implement the finite-volume discretization for the problem of modeling multiphase flow in porous media under the influence of viscous, gravity, and capillary forces while neglecting miscibility and taking into account rock and fluid compressibility. + +In here, we go over the governing equations :ref:`equations` that covers two different formulation options, followed by the :ref:`discretization`, and we conclude by providing a list of the solver :ref:`parameters` and an input :ref:`input_example`. + +.. _theory: + +Theory +========================= + +.. _equations: + +Governing Equations +------------------- + +Mass Conservation Equations +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +We consider a two-component system, say gas and water, flow in a compressible porous medium, in which both components can exist only in their corresponding phases of vapor and liquid. The gas and water components are denoted by the subscripts :math:`g` and +:math:`w`, respectively. Moreover, the liquid, which is the wetting phase, and the vapor, the non-wetting phase, are denoted by the subscripts :math:`\ell` and +:math:`v`, respectively. The mass conservation laws are expressed as: + +.. math:: + \frac{\partial}{\partial t} (\phi\rho_v S_v) + \nabla \cdot (\rho_v \boldsymbol{u}_v) = \rho_v q_v, + +and +.. math:: + \frac{\partial}{\partial t} (\phi\rho_\ell S_\ell) + \nabla \cdot (\rho_\ell \boldsymbol{u}_\ell) = \rho_\ell q_\ell, + + + +where :math:`\phi(\bold{x},p)` is the porosity of the medium which is a function of pressure, +:math:`S_\ell(\bold{x},t)` is the saturation of the phase +:math:`\ell` and similarly for the phase :math:`v`, and :math:`t` is the time. The source/sink terms :math:`q_{\ell}` and :math:`q_{v}` are +positive for injection and negative for production. The phase +velocity, :math:`\boldsymbol{u}_\ell`` and :math:`\boldsymbol{u}_v`$`, are defined using +the multiphase extension of Darcy's law (conservation of momentum) as + +.. math:: +\boldsymbol{u}_\ell := -k\lambda_\ell(\nabla p_\ell - \rho_\ell g \nabla z), + +and +.. math:: +\boldsymbol{u}_v := -k\lambda_v(\nabla p_v - \rho_v g \nabla z). + +Here, :math:`k(\bold{x})` is the scalar absolute permeability of the medium, :math:`\lambda_\ell` is the phase mobility of the liquid phase defined as :math:`k_{r\ell}/\mu_\ell`, where :math:`k_{r\ell}(\bold{x},S_\ell)` is the phase relative permeability, :math:`\mu_\ell` is the phase viscosity, and :math:`\rho_{\ell}` is the phase density. +These are also defined similarly for the vapor phase. In both cases we assume that the relative permeabilities are strictly increasing functions of their own saturation. +The gravitational acceleration is denoted by :math:`g`, and the +depth by :math:`z` (positive going downward). +The conservation of mass equations are constrained by the volume contraint equation: +.. math:: +S_{\ell} + S_v = 1, + +Moreover, the capillary pressure constraint relates the two phase pressures with +.. math:: +P_{c}(S_{\ell}) = p_{v} - p_{\ell}. + +We assume that capillary pressure is a strictly decreasing function of the wetting-phase saturation. + +The evaluation of the relative permeabilities, capillary pressures, and +viscosities is reviewed in the section about :doc:`/coreComponents/constitutive/docs/Constitutive`. + +We note that the formulation currently implemented in GEOS is isothermal. + +To summarize, the Immiscible multiphase flow solver assembles a set of :math:`n_p+1` +equations in each element, i.e., :math:`n_p` mass conservation equations and one volume constraint equation. + +==================== =========================== +Number of equations Equation type +==================== =========================== +:math:`n_p` Mass conservation equations +1 Volume constraint +==================== =========================== + +.. _primary_variables: + +Primary Variables +------------------ + +There are two formulations implemented in GEOS for the Immiscible multiphsae solver and both formulations are based on +:math:`n_p+1` primary variables, namely, one pressure, :math:`p`, and +:math:`n_p` phase volume fractions, :math:`S_{p}`. + +=========================== =========================== +Number of primary variables Variable type +=========================== =========================== +1 Pressure +:math:`n_p - 1` Phase volume fractions +=========================== =========================== + +The main formulation is the standard formulation which solves the individual components mass conservation equations. Also, another formulation based on the total mass flux is implemented which is useful for multiple purposes such as hybrid upwinding techniques and sequential finite volume methods. This latter formulation is explained next. + +Flow and Transport Equations +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +To develop this formulation we use a flux approximation as required by the finite-volume numerical solution scheme. +Thus, we choose to construct this approximation in fractional flow form, and with this we will be able to show the coupling between the different physical processes. This formulation is obtained by decomposing the governing equations into a flow problem for both phases and a transport problem for one of the two phases. +To obtain this decomposition, we use a total-mass balance formulation by summing both components mass conversation equations and then using the mass constraint to result in the following elliptic PDE governing the temporal evolution of the pressure field: +.. math:: + \frac{\partial}{\partial t}(\phi \rho_t) + \nabla \cdot (\rho_{\ell} \boldsymbol{u}_{\ell} + \rho_{v} \boldsymbol{u}_{v}) = \rho_{\ell} q_{\ell} + \rho_{v} q_{v}, + +where +.. math:: + \rho_t = \rho_{\ell}S_{\ell}+\rho_{v}S_{v} + +and we defined a total mass flux as +.. math:: +\boldsymbol{U}_T := \rho_{\ell} \boldsymbol{u}_{\ell} + \rho_{v} \boldsymbol{u}_{v}= -k (\rho_{\ell} \lambda_{\ell} + \rho_{v} \lambda_{v}) \nabla p + k ( \lambda_{\ell} \rho^2_{\ell} + \lambda_{v} \rho^2_{v}) g \nabla z + k \rho_{\ell}\lambda_{\ell} \nabla P_{c}. + +Next, the highly nonlinear parabolic transport equation is obtained by using this total mass flux to formally eliminate the pressure variable from the individual components mass conservation equations, yielding +.. math:: +{ +\frac{\partial}{\partial t}(\phi\rho_v S_v) + \nabla \cdot F_v + = + \rho_v q_v,} +and +.. math:: +{ +\frac{\partial}{\partial t}(\phi\rho_\ell S_\ell) + \nabla \cdot F_\ell + = +\rho_\ell q_\ell,} + +where the flow flux for each phase is defined as +.. math:: +{ +F_{\ell} := +\underbrace{\frac{\rho_\ell \lambda_\ell}{\rho_\ell \lambda_\ell+\rho_v \lambda_v}\boldsymbol{U}_T}_{\substack{\text{viscous} \\ \text{term}}} + +\underbrace{k \frac{\rho_\ell \lambda_\ell\rho_v \lambda_v}{\rho_\ell \lambda_\ell+\rho_v \lambda_v}(\rho_\ell - \rho_v) +g\nabla z}_{\substack{\text{buoyancy} \\ \text{term}}} ++ +\underbrace{k \frac{\rho_\ell \lambda_\ell\rho_v \lambda_v}{\rho_\ell \lambda_\ell+\rho_v \lambda_v} ( \nabla P_{c})}_{\substack{\text{capillary} \\ \text{term}}},} + +and +.. math:: +{ +F_{v} := +\underbrace{\frac{\rho_v \lambda_v}{\rho_\ell \lambda_\ell+\rho_v \lambda_v}\boldsymbol{U}_T}_{\substack{\text{viscous} \\ \text{term}}} + +\underbrace{k \frac{\rho_\ell \lambda_\ell\rho_v \lambda_v}{\rho_\ell \lambda_\ell+\rho_v \lambda_v}(\rho_v - \rho_\ell) +g\nabla z}_{\substack{\text{buoyancy} \\ \text{term}}} +- +\underbrace{k \frac{\rho_\ell \lambda_\ell\rho_v \lambda_v}{\rho_\ell \lambda_\ell+\rho_v \lambda_v} (\nabla P_{c})}_{\substack{\text{capillary} \\ \text{term}}},} + + +.. _discretization: + +Discretization +-------------- + +Spatial Discretization +~~~~~~~~~~~~~~~~~~~~~~ + +The governing equations are discretized using standard cell-centered finite-volume +discretization. + +In the approximation of the flux term at the interface between two control volumes, +the calculation of the pressure stencil is general and will ultimately support a +Multi-Point Flux Approximation (MPFA) approach. The current implementation of the +transmissibility calculation is reviewed in the section about +:doc:`/coreComponents/discretizationMethods/docs/NumericalMethodsManager`. + +The approximation of the dynamic transport coefficients multiplying the discrete +potential difference (e.g., the phase mobilities) is performed with a first-order +phase-per-phase single-point upwinding based on the sign of the phase potential difference +at the interface. + +Temporal Discretization +~~~~~~~~~~~~~~~~~~~~~~~ + +The immiscible multiphase solver uses a fully implicit (backward Euler) temporal discretization. + +.. _solution_strategy: + +Solution Strategy +----------------- + +The nonlinear solution strategy is based on Newton's method. +At each Newton iteration, the solver assembles a residual vector, :math:`R`, +collecting the :math:`n_p` discrete mass conservation equations and the volume +constraint for all the control volumes. + +.. _parameters: + +Parameters +=========== + +The following attributes are supported: + +.. include:: /docs/sphinx/datastructure/ImmiscibleMultiphaseFlow.rst + +.. _input_example: + +Example +========================= + +.. literalinclude:: ../../../../../inputFiles/immiscibleMultiphaseFlow/immiscible_2phaseFlow_1d.xml + :language: xml + :start-after: + :end-before: + diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp index e9d714c9096..15f2f019a58 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp @@ -44,6 +44,7 @@ #include "physicsSolvers/fluidFlow/kernels/compositional/RelativePermeabilityUpdateKernel.hpp" #include "physicsSolvers/fluidFlow/kernels/compositional/CapillaryPressureUpdateKernel.hpp" #include "physicsSolvers/PhysicsSolverBaseKernels.hpp" +#include "physicsSolvers/fluidFlow/kernels/compositional/KernelLaunchSelectors.hpp" namespace geos { @@ -763,6 +764,330 @@ class FaceBasedAssemblyKernelFactory } }; + +/******************************** AccumulationKernel ********************************/ + +static constexpr real64 minDensForDivision = 1e-10; + +enum class KernelFlags +{ + // SimpleAccumulation = 1 << 0, // 1 + TotalMassEquation = 1 << 1, // 2 + /// Add more flags like that if needed: + // Flag3 = 1 << 2, // 4 + // Flag4 = 1 << 3, // 8 + // Flag5 = 1 << 4, // 16 + // Flag6 = 1 << 5, // 32 + // Flag7 = 1 << 6, // 64 + // Flag8 = 1 << 7 //128 +}; +/** + * @class AccumulationKernel + * @tparam NUM_COMP number of fluid phases + * @tparam NUM_DOF number of degrees of freedom + * @brief Define the interface for the assembly kernel in charge of accumulation + */ + +template< integer NUM_EQN, integer NUM_DOF > +class AccumulationKernel +{ +public: + + /// Number of fluid phases + integer const m_numPhases; + + /// Compute time value for the number of degrees of freedom + static constexpr integer numDof = NUM_DOF; + + /// Compute time value for the number of equations + static constexpr integer numEqn = NUM_DOF; + + /** + * @brief Constructor + * @param[in] numPhases the number of fluid phases + * @param[in] rankOffset the offset of my MPI rank + * @param[in] dofKey the string key to retrieve the degress of freedom numbers + * @param[in] subRegion the element subregion + * @param[in] fluid the fluid model + * @param[in] solid the solid model + * @param[inout] localMatrix the local CRS matrix + * @param[inout] localRhs the local right-hand side vector + */ + AccumulationKernel( localIndex const numPhases, + globalIndex const rankOffset, + string const dofKey, + ElementSubRegionBase const & subRegion, + constitutive::TwoPhaseFluid const & fluid, + constitutive::CoupledSolidBase const & solid, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs, + BitFlags< KernelFlags > const kernelFlags ) + : m_numPhases( numPhases ), + m_rankOffset( rankOffset ), + m_dofNumber( subRegion.getReference< array1d< globalIndex > >( dofKey ) ), + m_elemGhostRank( subRegion.ghostRank() ), + m_volume( subRegion.getElementVolume() ), + m_porosity( solid.getPorosity() ), + m_dPoro_dPres( solid.getDporosity_dPressure() ), + m_phaseVolFrac( subRegion.getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >() ), + m_phaseDens( fluid.phaseDensity() ), + m_dPhaseDens( fluid.dPhaseDensity() ), + m_phaseMass_n( subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseMass_n >() ), + m_localMatrix( localMatrix ), + m_localRhs( localRhs ), + m_kernelFlags( kernelFlags ) + {} + + /** + * @struct StackVariables + * @brief Kernel variables (dof numbers, jacobian and residual) located on the stack + */ + struct StackVariables + { +public: + + // Pore volume information (used by both accumulation and volume balance) + + /// Pore volume at time n+1 + real64 poreVolume = 0.0; + + /// Derivative of pore volume with respect to pressure + real64 dPoreVolume_dPres = 0.0; + + // Residual information + + /// Index of the local row corresponding to this element + localIndex localRow = -1; + + /// Indices of the matrix rows/columns corresponding to the dofs in this element + globalIndex dofIndices[numDof]{}; + + /// C-array storage for the element local residual vector (all equations except volume balance) + real64 localResidual[numEqn]{}; + + /// C-array storage for the element local Jacobian matrix (all equations except volume balance, all dofs) + real64 localJacobian[numEqn][numDof]{}; + + }; + + /** + * @brief Getter for the ghost rank of an element + * @param[in] ei the element index + * @return the ghost rank of the element + */ + GEOS_HOST_DEVICE + integer elemGhostRank( localIndex const ei ) const + { return m_elemGhostRank( ei ); } + + + /** + * @brief Performs the setup phase for the kernel. + * @param[in] ei the element index + * @param[in] stack the stack variables + */ + GEOS_HOST_DEVICE + void setup( localIndex const ei, + StackVariables & stack ) const + { + // initialize the pore volume + stack.poreVolume = m_volume[ei] * m_porosity[ei][0]; + stack.dPoreVolume_dPres = m_volume[ei] * m_dPoro_dPres[ei][0]; + + // set row index and degrees of freedom indices for this element + stack.localRow = m_dofNumber[ei] - m_rankOffset; + for( integer idof = 0; idof < numDof; ++idof ) + { + stack.dofIndices[idof] = m_dofNumber[ei] + idof; + } + } + + /** + * @brief Compute the local accumulation contributions to the residual and Jacobian + * @tparam FUNC the type of the function that can be used to customize the kernel + * @param[in] ei the element index + * @param[inout] stack the stack variables + * @param[in] phaseAmountKernelOp the function used to customize the kernel + */ + template< typename FUNC = NoOpFunc > + GEOS_HOST_DEVICE + void computeAccumulation( localIndex const ei, + StackVariables & stack, + FUNC && phaseAmountKernelOp = NoOpFunc{} ) const + { + int signPotDiff[2] = {1, -1}; + // ic - index of component whose conservation equation is assembled + // (i.e. row number in local matrix) + for( integer ip = 0; ip < m_numPhases; ++ip ) + { + real64 const phaseMass = stack.poreVolume * m_phaseVolFrac[ei][ip] * m_phaseDens[ei][0][ip]; + real64 const phaseMass_n = m_phaseMass_n[ei][ip]; + + stack.localResidual[ip] += phaseMass - phaseMass_n; + + real64 const dPhaseMass_dP = stack.dPoreVolume_dPres * m_phaseVolFrac[ei][ip] * m_phaseDens[ei][0][ip] + + stack.poreVolume * m_phaseVolFrac[ei][ip] * m_dPhaseDens[ei][0][ip][0]; + stack.localJacobian[ip][0] += dPhaseMass_dP; + + real64 const dPhaseMass_dS = stack.poreVolume * m_phaseDens[ei][0][ip]; + stack.localJacobian[ip][1] += signPotDiff[ip] * dPhaseMass_dS; + } + + } + + /** + * @brief Performs the complete phase for the kernel. + * @param[in] ei the element index + * @param[inout] stack the stack variables + */ + GEOS_HOST_DEVICE + void complete( localIndex const GEOS_UNUSED_PARAM( ei ), + StackVariables & stack ) const + { + using namespace compositionalMultiphaseUtilities; + + if( m_kernelFlags.isSet( KernelFlags::TotalMassEquation ) ) + { + // apply equation/variable change transformation to the component mass balance equations + real64 work[numDof]{}; + shiftRowsAheadByOneAndReplaceFirstRowWithColumnSum( m_numPhases, numDof, stack.localJacobian, work ); + shiftElementsAheadByOneAndReplaceFirstElementWithSum( m_numPhases, stack.localResidual ); + } + + // add contribution to residual and jacobian into: + // - the component mass balance equations (i = 0 to i = numComp-1) + // - the volume balance equations (i = numComp) + // note that numDof includes derivatives wrt temperature if this class is derived in ThermalKernels + integer const numRows = m_numPhases; + for( integer i = 0; i < numRows; ++i ) + { + m_localRhs[stack.localRow + i] += stack.localResidual[i]; + m_localMatrix.addToRow< serialAtomic >( stack.localRow + i, + stack.dofIndices, + stack.localJacobian[i], + numDof ); + } + } + + /** + * @brief Performs the kernel launch + * @tparam POLICY the policy used in the RAJA kernels + * @tparam KERNEL_TYPE the kernel type + * @param[in] numElems the number of elements + * @param[inout] kernelComponent the kernel component providing access to setup/compute/complete functions and stack variables + */ + template< typename POLICY, typename KERNEL_TYPE > + static void + launch( localIndex const numElems, + KERNEL_TYPE const & kernelComponent ) + { + GEOS_MARK_FUNCTION; + + forAll< POLICY >( numElems, [=] GEOS_HOST_DEVICE ( localIndex const ei ) + { + if( kernelComponent.elemGhostRank( ei ) >= 0 ) + { + return; + } + + typename KERNEL_TYPE::StackVariables stack; + + kernelComponent.setup( ei, stack ); + kernelComponent.computeAccumulation( ei, stack ); + kernelComponent.complete( ei, stack ); + } ); + } + +protected: + + /// Offset for my MPI rank + globalIndex const m_rankOffset; + + /// View on the dof numbers + arrayView1d< globalIndex const > const m_dofNumber; + + /// View on the ghost ranks + arrayView1d< integer const > const m_elemGhostRank; + + /// View on the element volumes + arrayView1d< real64 const > const m_volume; + + /// Views on the porosity + arrayView2d< real64 const > const m_porosity; + arrayView2d< real64 const > const m_dPoro_dPres; + + /// Views on the phase volume fractions + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const m_phaseVolFrac; + + /// Views on the phase densities + arrayView3d< real64 const, constitutive::multifluid::USD_PHASE > const m_phaseDens; + arrayView4d< real64 const, constitutive::multifluid::USD_PHASE_DC > const m_dPhaseDens; + + // View on component amount (mass) from previous time step + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > m_phaseMass_n; + + /// View on the local CRS matrix + CRSMatrixView< real64, globalIndex const > const m_localMatrix; + /// View on the local RHS + arrayView1d< real64 > const m_localRhs; + + BitFlags< KernelFlags > const m_kernelFlags; +}; + +/** + * @class AccumulationKernelFactory + */ +class AccumulationKernelFactory +{ +public: + + /** + * @brief Create a new kernel and launch + * @tparam POLICY the policy used in the RAJA kernel + * @param[in] numPhases the number of fluid phases + * @param[in] rankOffset the offset of my MPI rank + * @param[in] dofKey the string key to retrieve the degress of freedom numbers + * @param[in] subRegion the element subregion + * @param[in] fluid the fluid model + * @param[in] solid the solid model + * @param[inout] localMatrix the local CRS matrix + * @param[inout] localRhs the local right-hand side vector + */ + template< typename POLICY > + static void + createAndLaunch( integer const numPhases, + globalIndex const rankOffset, + integer const useTotalMassEquation, + string const dofKey, + ElementSubRegionBase const & subRegion, + constitutive::TwoPhaseFluid const & fluid, + constitutive::CoupledSolidBase const & solid, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) + { + + using namespace isothermalCompositionalMultiphaseBaseKernels::internal; + + kernelLaunchSelectorCompSwitch( numPhases, [&] ( auto NP ) + { + integer constexpr NUM_EQN = NP(); + integer constexpr NUM_DOF = NP(); + + BitFlags< KernelFlags > kernelFlags; + if( useTotalMassEquation ) + kernelFlags.set( KernelFlags::TotalMassEquation ); + // if( useSimpleAccumulation ) + // kernelFlags.set( KernelFlags::SimpleAccumulation ); + + AccumulationKernel< NUM_EQN, NUM_DOF > kernel( numPhases, rankOffset, dofKey, subRegion, + fluid, solid, localMatrix, localRhs, kernelFlags ); + AccumulationKernel< NUM_EQN, NUM_DOF >::template launch< POLICY >( subRegion.size(), kernel ); + } ); + } + +}; + + + /******************************** PhaseMobilityKernel ********************************/ /** From fa42877311d6764b4161c99b58693186170dced2 Mon Sep 17 00:00:00 2001 From: Ammara-14 Date: Thu, 21 Nov 2024 12:28:23 -0800 Subject: [PATCH 065/102] fixed code style and added a dedicated Kernel selector switch --- .../fluidFlow/ImmiscibleMultiphaseFlow.cpp | 22 ++--- .../docs/ImmiscibleMultiphaseFlow.rst | 86 ++++++++++++------- .../ImmiscibleMultiphaseKernels.hpp | 64 +++++++------- .../KernelLaunchSelectors.hpp | 57 ++++++++++++ 4 files changed, 152 insertions(+), 77 deletions(-) create mode 100644 src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/KernelLaunchSelectors.hpp diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp index 7270185f06f..e44069772f7 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp @@ -603,17 +603,17 @@ void ImmiscibleMultiphaseFlow::assembleAccumulationTerm( DomainPartition & domai CoupledSolidBase const & solid = getConstitutiveModel< CoupledSolidBase >( subRegion, solidName ); immiscibleMultiphaseKernels:: - AccumulationKernelFactory:: - createAndLaunch< parallelDevicePolicy<> >( m_numPhases, - dofManager.rankOffset(), - m_useTotalMassEquation, - dofKey, - subRegion, - fluid, - solid, - localMatrix, - localRhs ); - + AccumulationKernelFactory:: + createAndLaunch< parallelDevicePolicy<> >( m_numPhases, + dofManager.rankOffset(), + m_useTotalMassEquation, + dofKey, + subRegion, + fluid, + solid, + localMatrix, + localRhs ); + } ); } ); diff --git a/src/coreComponents/physicsSolvers/fluidFlow/docs/ImmiscibleMultiphaseFlow.rst b/src/coreComponents/physicsSolvers/fluidFlow/docs/ImmiscibleMultiphaseFlow.rst index b7e98af3c76..429acffd551 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/docs/ImmiscibleMultiphaseFlow.rst +++ b/src/coreComponents/physicsSolvers/fluidFlow/docs/ImmiscibleMultiphaseFlow.rst @@ -29,39 +29,45 @@ We consider a two-component system, say gas and water, flow in a compressible po :math:`v`, respectively. The mass conservation laws are expressed as: .. math:: - \frac{\partial}{\partial t} (\phi\rho_v S_v) + \nabla \cdot (\rho_v \boldsymbol{u}_v) = \rho_v q_v, + \frac{\partial}{\partial t} (\phi\rho_v S_v) + \nabla \cdot (\rho_v \boldsymbol{u}_v) = + \rho_v q_v, and + .. math:: - \frac{\partial}{\partial t} (\phi\rho_\ell S_\ell) + \nabla \cdot (\rho_\ell \boldsymbol{u}_\ell) = \rho_\ell q_\ell, + \frac{\partial}{\partial t} (\phi\rho_\ell S_\ell) + \nabla \cdot (\rho_\ell + \boldsymbol{u}_\ell) = \rho_\ell q_\ell, -where :math:`\phi(\bold{x},p)` is the porosity of the medium which is a function of pressure, -:math:`S_\ell(\bold{x},t)` is the saturation of the phase +where :math:`\phi(\mathbf{x})` is the porosity of the medium which is a function of pressure, +:math:`S_\ell(\mathbf{x},t)` is the saturation of the phase :math:`\ell` and similarly for the phase :math:`v`, and :math:`t` is the time. The source/sink terms :math:`q_{\ell}` and :math:`q_{v}` are positive for injection and negative for production. The phase velocity, :math:`\boldsymbol{u}_\ell`` and :math:`\boldsymbol{u}_v`$`, are defined using the multiphase extension of Darcy's law (conservation of momentum) as -.. math:: -\boldsymbol{u}_\ell := -k\lambda_\ell(\nabla p_\ell - \rho_\ell g \nabla z), + .. math:: + \boldsymbol{u}_\ell := -k\lambda_\ell(\nabla p_\ell - \rho_\ell g \nabla z), and -.. math:: -\boldsymbol{u}_v := -k\lambda_v(\nabla p_v - \rho_v g \nabla z). -Here, :math:`k(\bold{x})` is the scalar absolute permeability of the medium, :math:`\lambda_\ell` is the phase mobility of the liquid phase defined as :math:`k_{r\ell}/\mu_\ell`, where :math:`k_{r\ell}(\bold{x},S_\ell)` is the phase relative permeability, :math:`\mu_\ell` is the phase viscosity, and :math:`\rho_{\ell}` is the phase density. + .. math:: + \boldsymbol{u}_v := -k\lambda_v(\nabla p_v - \rho_v g \nabla z). + +Here, :math:`k(\mathbf{x})` is the scalar absolute permeability of the medium, :math:`\lambda_\ell` is the phase mobility of the liquid phase defined as :math:`k_{r\ell}/\mu_\ell`, where :math:`k_{r\ell}(\mathbf{x},S_\ell)` is the phase relative permeability, :math:`\mu_\ell` is the phase viscosity, and :math:`\rho_{\ell}` is the phase density. These are also defined similarly for the vapor phase. In both cases we assume that the relative permeabilities are strictly increasing functions of their own saturation. The gravitational acceleration is denoted by :math:`g`, and the depth by :math:`z` (positive going downward). The conservation of mass equations are constrained by the volume contraint equation: + .. math:: -S_{\ell} + S_v = 1, + S_{\ell} + S_v = 1, Moreover, the capillary pressure constraint relates the two phase pressures with + .. math:: -P_{c}(S_{\ell}) = p_{v} - p_{\ell}. + P_{c}(S_{\ell}) = p_{v} - p_{\ell}. We assume that capillary pressure is a strictly decreasing function of the wetting-phase saturation. @@ -89,6 +95,7 @@ There are two formulations implemented in GEOS for the Immiscible multiphsae sol :math:`n_p+1` primary variables, namely, one pressure, :math:`p`, and :math:`n_p` phase volume fractions, :math:`S_{p}`. + =========================== =========================== Number of primary variables Variable type =========================== =========================== @@ -103,49 +110,64 @@ Flow and Transport Equations To develop this formulation we use a flux approximation as required by the finite-volume numerical solution scheme. Thus, we choose to construct this approximation in fractional flow form, and with this we will be able to show the coupling between the different physical processes. This formulation is obtained by decomposing the governing equations into a flow problem for both phases and a transport problem for one of the two phases. To obtain this decomposition, we use a total-mass balance formulation by summing both components mass conversation equations and then using the mass constraint to result in the following elliptic PDE governing the temporal evolution of the pressure field: + .. math:: \frac{\partial}{\partial t}(\phi \rho_t) + \nabla \cdot (\rho_{\ell} \boldsymbol{u}_{\ell} + \rho_{v} \boldsymbol{u}_{v}) = \rho_{\ell} q_{\ell} + \rho_{v} q_{v}, where + .. math:: \rho_t = \rho_{\ell}S_{\ell}+\rho_{v}S_{v} and we defined a total mass flux as + .. math:: -\boldsymbol{U}_T := \rho_{\ell} \boldsymbol{u}_{\ell} + \rho_{v} \boldsymbol{u}_{v}= -k (\rho_{\ell} \lambda_{\ell} + \rho_{v} \lambda_{v}) \nabla p + k ( \lambda_{\ell} \rho^2_{\ell} + \lambda_{v} \rho^2_{v}) g \nabla z + k \rho_{\ell}\lambda_{\ell} \nabla P_{c}. + \boldsymbol{U}_T := \rho_{\ell} \boldsymbol{u}_{\ell} + \rho_{v} \boldsymbol{u}_{v}= -k (\rho_{\ell} \lambda_{\ell} + \rho_{v} \lambda_{v}) \nabla p + k ( \lambda_{\ell} \rho^2_{\ell} + \lambda_{v} \rho^2_{v}) g \nabla z + k \rho_{\ell}\lambda_{\ell} \nabla P_{c}. Next, the highly nonlinear parabolic transport equation is obtained by using this total mass flux to formally eliminate the pressure variable from the individual components mass conservation equations, yielding + .. math:: -{ -\frac{\partial}{\partial t}(\phi\rho_v S_v) + \nabla \cdot F_v + \frac{\partial}{\partial t}(\phi\rho_v S_v) + \nabla \cdot F_v = - \rho_v q_v,} + \rho_v q_v, + and + .. math:: -{ -\frac{\partial}{\partial t}(\phi\rho_\ell S_\ell) + \nabla \cdot F_\ell + + \frac{\partial}{\partial t}(\phi\rho_\ell S_\ell) + \nabla \cdot F_\ell = -\rho_\ell q_\ell,} + \rho_\ell q_\ell, where the flow flux for each phase is defined as + .. math:: -{ -F_{\ell} := -\underbrace{\frac{\rho_\ell \lambda_\ell}{\rho_\ell \lambda_\ell+\rho_v \lambda_v}\boldsymbol{U}_T}_{\substack{\text{viscous} \\ \text{term}}} + -\underbrace{k \frac{\rho_\ell \lambda_\ell\rho_v \lambda_v}{\rho_\ell \lambda_\ell+\rho_v \lambda_v}(\rho_\ell - \rho_v) -g\nabla z}_{\substack{\text{buoyancy} \\ \text{term}}} -+ -\underbrace{k \frac{\rho_\ell \lambda_\ell\rho_v \lambda_v}{\rho_\ell \lambda_\ell+\rho_v \lambda_v} ( \nabla P_{c})}_{\substack{\text{capillary} \\ \text{term}}},} + { + F_{\ell} := + \frac{\rho_\ell \lambda_\ell}{\rho_\ell \lambda_\ell+\rho_v + \lambda_v}\boldsymbol{U}_T} + + k \frac{\rho_\ell \lambda_\ell\rho_v \lambda_v}{\rho_\ell \lambda_\ell+\rho_v + \lambda_v}(\rho_\ell - \rho_v) + g\nabla z + + + k \frac{\rho_\ell \lambda_\ell\rho_v \lambda_v}{\rho_\ell \lambda_\ell+\rho_v + \lambda_v} ( \nabla P_{c}) and + .. math:: -{ -F_{v} := -\underbrace{\frac{\rho_v \lambda_v}{\rho_\ell \lambda_\ell+\rho_v \lambda_v}\boldsymbol{U}_T}_{\substack{\text{viscous} \\ \text{term}}} + -\underbrace{k \frac{\rho_\ell \lambda_\ell\rho_v \lambda_v}{\rho_\ell \lambda_\ell+\rho_v \lambda_v}(\rho_v - \rho_\ell) -g\nabla z}_{\substack{\text{buoyancy} \\ \text{term}}} -- -\underbrace{k \frac{\rho_\ell \lambda_\ell\rho_v \lambda_v}{\rho_\ell \lambda_\ell+\rho_v \lambda_v} (\nabla P_{c})}_{\substack{\text{capillary} \\ \text{term}}},} + { + F_{v} := + \frac{\rho_v \lambda_v}{\rho_\ell \lambda_\ell+\rho_v + \lambda_v}\boldsymbol{U}_T} + + k \frac{\rho_\ell \lambda_\ell\rho_v \lambda_v}{\rho_\ell \lambda_\ell+\rho_v + \lambda_v}(\rho_v - \rho_\ell) + g\nabla z + - + k \frac{\rho_\ell \lambda_\ell\rho_v \lambda_v}{\rho_\ell \lambda_\ell+\rho_v + \lambda_v} ( \nabla P_{c}) + + .. _discretization: diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp index 15f2f019a58..30ccd2bafee 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp @@ -44,7 +44,7 @@ #include "physicsSolvers/fluidFlow/kernels/compositional/RelativePermeabilityUpdateKernel.hpp" #include "physicsSolvers/fluidFlow/kernels/compositional/CapillaryPressureUpdateKernel.hpp" #include "physicsSolvers/PhysicsSolverBaseKernels.hpp" -#include "physicsSolvers/fluidFlow/kernels/compositional/KernelLaunchSelectors.hpp" +#include "physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/KernelLaunchSelectors.hpp" namespace geos { @@ -226,7 +226,7 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase /** * @brief Constructor for the kernel interface - * @param[in] numPhases number of fluid phases + * @param[in] numPhases number of fluid phases * @param[in] rankOffset the offset of my MPI rank * @param[in] stencilWrapper reference to the stencil wrapper * @param[in] dofNumberAccessor @@ -638,7 +638,7 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase shiftBlockElementsAheadByOneAndReplaceFirstElementWithSum( m_numPhases, numEqn, stack.numFluxElems, stack.localFlux ); } - + // add contribution to residual and jacobian into: // - the mass balance equation // note that numDof includes derivatives wrt temperature if this class is derived in ThermalKernels @@ -767,13 +767,12 @@ class FaceBasedAssemblyKernelFactory /******************************** AccumulationKernel ********************************/ -static constexpr real64 minDensForDivision = 1e-10; - enum class KernelFlags { - // SimpleAccumulation = 1 << 0, // 1 - TotalMassEquation = 1 << 1, // 2 + TotalMassEquation = 1 << 0, // 1 + /// Add more flags like that if needed: + // Flag2 = 1 << 1, // 2 // Flag3 = 1 << 2, // 4 // Flag4 = 1 << 3, // 8 // Flag5 = 1 << 4, // 16 @@ -783,7 +782,7 @@ enum class KernelFlags }; /** * @class AccumulationKernel - * @tparam NUM_COMP number of fluid phases + * @tparam NUM_EQN number of fluid phases * @tparam NUM_DOF number of degrees of freedom * @brief Define the interface for the assembly kernel in charge of accumulation */ @@ -800,7 +799,7 @@ class AccumulationKernel static constexpr integer numDof = NUM_DOF; /// Compute time value for the number of equations - static constexpr integer numEqn = NUM_DOF; + static constexpr integer numEqn = NUM_EQN; /** * @brief Constructor @@ -812,6 +811,7 @@ class AccumulationKernel * @param[in] solid the solid model * @param[inout] localMatrix the local CRS matrix * @param[inout] localRhs the local right-hand side vector + * @param[inout] kernelFlags the kernel options */ AccumulationKernel( localIndex const numPhases, globalIndex const rankOffset, @@ -846,7 +846,7 @@ class AccumulationKernel { public: - // Pore volume information (used by both accumulation and volume balance) + // Pore volume information (used by both accumulation) /// Pore volume at time n+1 real64 poreVolume = 0.0; @@ -906,31 +906,30 @@ class AccumulationKernel * @tparam FUNC the type of the function that can be used to customize the kernel * @param[in] ei the element index * @param[inout] stack the stack variables - * @param[in] phaseAmountKernelOp the function used to customize the kernel */ template< typename FUNC = NoOpFunc > GEOS_HOST_DEVICE void computeAccumulation( localIndex const ei, StackVariables & stack, - FUNC && phaseAmountKernelOp = NoOpFunc{} ) const + FUNC = NoOpFunc{} ) const { - int signPotDiff[2] = {1, -1}; - // ic - index of component whose conservation equation is assembled - // (i.e. row number in local matrix) - for( integer ip = 0; ip < m_numPhases; ++ip ) - { - real64 const phaseMass = stack.poreVolume * m_phaseVolFrac[ei][ip] * m_phaseDens[ei][0][ip]; - real64 const phaseMass_n = m_phaseMass_n[ei][ip]; + int signPotDiff[2] = {1, -1}; + // ip - index of phase/component whose conservation equation is assembled + // (i.e. row number in local matrix) + for( integer ip = 0; ip < m_numPhases; ++ip ) + { + real64 const phaseMass = stack.poreVolume * m_phaseVolFrac[ei][ip] * m_phaseDens[ei][0][ip]; + real64 const phaseMass_n = m_phaseMass_n[ei][ip]; - stack.localResidual[ip] += phaseMass - phaseMass_n; + stack.localResidual[ip] += phaseMass - phaseMass_n; - real64 const dPhaseMass_dP = stack.dPoreVolume_dPres * m_phaseVolFrac[ei][ip] * m_phaseDens[ei][0][ip] - + stack.poreVolume * m_phaseVolFrac[ei][ip] * m_dPhaseDens[ei][0][ip][0]; - stack.localJacobian[ip][0] += dPhaseMass_dP; + real64 const dPhaseMass_dP = stack.dPoreVolume_dPres * m_phaseVolFrac[ei][ip] * m_phaseDens[ei][0][ip] + + stack.poreVolume * m_phaseVolFrac[ei][ip] * m_dPhaseDens[ei][0][ip][0]; + stack.localJacobian[ip][0] += dPhaseMass_dP; - real64 const dPhaseMass_dS = stack.poreVolume * m_phaseDens[ei][0][ip]; - stack.localJacobian[ip][1] += signPotDiff[ip] * dPhaseMass_dS; - } + real64 const dPhaseMass_dS = stack.poreVolume * m_phaseDens[ei][0][ip]; + stack.localJacobian[ip][1] += signPotDiff[ip] * dPhaseMass_dS; + } } @@ -954,8 +953,7 @@ class AccumulationKernel } // add contribution to residual and jacobian into: - // - the component mass balance equations (i = 0 to i = numComp-1) - // - the volume balance equations (i = numComp) + // - the component mass balance equations (i = 0 to i = numPhase - 1) // note that numDof includes derivatives wrt temperature if this class is derived in ThermalKernels integer const numRows = m_numPhases; for( integer i = 0; i < numRows; ++i ) @@ -1045,6 +1043,7 @@ class AccumulationKernelFactory * @tparam POLICY the policy used in the RAJA kernel * @param[in] numPhases the number of fluid phases * @param[in] rankOffset the offset of my MPI rank + * @param[inout] useTotalMassEquation option for using total mass equation * @param[in] dofKey the string key to retrieve the degress of freedom numbers * @param[in] subRegion the element subregion * @param[in] fluid the fluid model @@ -1064,10 +1063,8 @@ class AccumulationKernelFactory CRSMatrixView< real64, globalIndex const > const & localMatrix, arrayView1d< real64 > const & localRhs ) { - - using namespace isothermalCompositionalMultiphaseBaseKernels::internal; - kernelLaunchSelectorCompSwitch( numPhases, [&] ( auto NP ) + geos::immiscibleMultiphaseKernels::kernelLaunchSelectorPhaseSwitch( numPhases, [&] ( auto NP ) { integer constexpr NUM_EQN = NP(); integer constexpr NUM_DOF = NP(); @@ -1075,11 +1072,9 @@ class AccumulationKernelFactory BitFlags< KernelFlags > kernelFlags; if( useTotalMassEquation ) kernelFlags.set( KernelFlags::TotalMassEquation ); - // if( useSimpleAccumulation ) - // kernelFlags.set( KernelFlags::SimpleAccumulation ); AccumulationKernel< NUM_EQN, NUM_DOF > kernel( numPhases, rankOffset, dofKey, subRegion, - fluid, solid, localMatrix, localRhs, kernelFlags ); + fluid, solid, localMatrix, localRhs, kernelFlags ); AccumulationKernel< NUM_EQN, NUM_DOF >::template launch< POLICY >( subRegion.size(), kernel ); } ); } @@ -1180,6 +1175,7 @@ class PhaseMobilityKernel dPhaseMob[ip][Deriv::dS] = dRelPerm_dS * density / viscosity; // } + // call the lambda in the phase loop to allow the reuse of the relperm, density, viscosity, and mobility // possible use: assemble the derivatives wrt temperature phaseMobilityKernelOp( ip, phaseMob[ip], dPhaseMob[ip] ); diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/KernelLaunchSelectors.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/KernelLaunchSelectors.hpp new file mode 100644 index 00000000000..f1548bb2c7e --- /dev/null +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/KernelLaunchSelectors.hpp @@ -0,0 +1,57 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * SPDX-License-Identifier: LGPL-2.1-only + * + * Copyright (c) 2016-2024 Lawrence Livermore National Security LLC + * Copyright (c) 2018-2024 Total, S.A + * Copyright (c) 2018-2024 The Board of Trustees of the Leland Stanford Junior University + * Copyright (c) 2023-2024 Chevron + * Copyright (c) 2019- GEOS/GEOSX Contributors + * All rights reserved + * + * See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details. + * ------------------------------------------------------------------------------------------------------------ + */ + +/** + * @file KernelLaunchSelector.hpp + */ + +#ifndef GEOS_PHYSICSSOLVERS_FLUIDFLOW_IMMISCIBLE_KERNELLAUNCHSELECTOR_HPP +#define GEOS_PHYSICSSOLVERS_FLUIDFLOW_IMMISCIBLE_KERNELLAUNCHSELECTOR_HPP + +//#include "codingUtilities/Utilities.hpp" +//#include "common/DataLayouts.hpp" +//#include "common/DataTypes.hpp" +//#include "common/GEOS_RAJA_Interface.hpp" + +namespace geos +{ + +namespace immiscibleMultiphaseKernels +{ + +/******************************** Kernel launch machinery ********************************/ + + +template< typename T, typename LAMBDA > +void kernelLaunchSelectorPhaseSwitch( T value, LAMBDA && lambda ) +{ + static_assert( std::is_integral< T >::value, "kernelLaunchSelectorPhaseSwitch: type should be integral" ); + + switch( value ) + { + case 2: + { lambda( std::integral_constant< T, 2 >() ); return; } + default: + { GEOS_ERROR( "Unsupported number of phases: " << value ); } + } + +} + +} // namespace immiscibleMultiphaseKernels + +} // namespace geos + + +#endif //GEOS_PHYSICSSOLVERS_FLUIDFLOW_IMMISCIBLE_KERNELLAUNCHSELECTOR_HPP From 83783e6aedfe1e27675999508bdb468215b77e81 Mon Sep 17 00:00:00 2001 From: DENEL Bertrand Date: Thu, 21 Nov 2024 18:46:17 -0600 Subject: [PATCH 066/102] Fixed doc references. --- .../immiscible_2phaseFlow_1d.xml | 3 ++- .../physicsSolvers/PhysicsSolvers.rst | 2 ++ .../fluidFlow/docs/ImmiscibleMultiphaseFlow.rst | 16 ++++++++-------- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscible_2phaseFlow_1d.xml b/inputFiles/immiscibleMultiphaseFlow/immiscible_2phaseFlow_1d.xml index 8247d534a28..18ccf6272eb 100644 --- a/inputFiles/immiscibleMultiphaseFlow/immiscible_2phaseFlow_1d.xml +++ b/inputFiles/immiscibleMultiphaseFlow/immiscible_2phaseFlow_1d.xml @@ -1,6 +1,7 @@ + - + Date: Thu, 21 Nov 2024 19:25:34 -0600 Subject: [PATCH 067/102] Used pre-existing Geos readTable function. --- .../fluid/twophasefluid/TwoPhaseFluid.cpp | 47 +------------------ .../fluid/twophasefluid/TwoPhaseFluid.hpp | 12 ----- 2 files changed, 2 insertions(+), 57 deletions(-) diff --git a/src/coreComponents/constitutive/fluid/twophasefluid/TwoPhaseFluid.cpp b/src/coreComponents/constitutive/fluid/twophasefluid/TwoPhaseFluid.cpp index b0fc13116fa..3b119e393d8 100644 --- a/src/coreComponents/constitutive/fluid/twophasefluid/TwoPhaseFluid.cpp +++ b/src/coreComponents/constitutive/fluid/twophasefluid/TwoPhaseFluid.cpp @@ -17,6 +17,7 @@ * @file TwoPhaseFluid.cpp */ +#include "constitutive/fluid/multifluid/CO2Brine/functions/PVTFunctionHelpers.hpp" // for readTable #include "TwoPhaseFluid.hpp" #include "TwoPhaseFluidFields.hpp" @@ -114,50 +115,6 @@ void TwoPhaseFluid::postInputInitialization() } -void -TwoPhaseFluid::readTable( string const & fileName, - integer minRowLength, - array1d< array1d< real64 > > & data ) -{ - std::ifstream is( fileName ); - GEOS_THROW_IF( !is.is_open(), - GEOS_FMT( "{}: could not open file: {}", getFullName(), fileName ), - InputError ); - - // Read line-by-line until eof - string str; - while( std::getline( is, str ) ) - { - // Remove whitespace and end-of-line characters, if any - str = stringutilities::trim( str, " \r" ); - - // Remove # and -- (Eclipse-style) comments - str = stringutilities::removeStringAndFollowingContent( str, "#" ); - str = stringutilities::removeStringAndFollowingContent( str, "--" ); - - // Skip empty or comment-only strings - if( str.empty() ) - continue; - - // Add and read a new line entry - array1d< real64 > newLine = stringutilities::fromStringToArray< real64 >( str ); - if( !newLine.empty() ) - { - data.emplace_back( std::move( newLine ) ); - } - } - - is.close(); - - for( localIndex i = 0; i < data.size(); ++i ) - { - GEOS_THROW_IF( data[i].size() < minRowLength, - GEOS_FMT( "{}: too few entries in row {} of table {}, minimum {} required", getFullName(), i, fileName, minRowLength ), - InputError ); - } -} - - void TwoPhaseFluid::fillData( integer const ip, array1d< array1d< real64 > > const & tableValues ) { @@ -215,7 +172,7 @@ void TwoPhaseFluid::readInputDataFromFileTableFunctions() for( integer ip = 0; ip < 2; ++ip ) { tableValues.clear(); - readTable( m_tableFiles[ip], 3, tableValues ); + geos::constitutive::PVTProps::BlackOilTables::readTable( m_tableFiles[ip], 3, tableValues ); fillData( ip, tableValues ); } } diff --git a/src/coreComponents/constitutive/fluid/twophasefluid/TwoPhaseFluid.hpp b/src/coreComponents/constitutive/fluid/twophasefluid/TwoPhaseFluid.hpp index 9de6a4bfee4..d1da2681a25 100644 --- a/src/coreComponents/constitutive/fluid/twophasefluid/TwoPhaseFluid.hpp +++ b/src/coreComponents/constitutive/fluid/twophasefluid/TwoPhaseFluid.hpp @@ -246,18 +246,6 @@ class TwoPhaseFluid : public ConstitutiveBase void fillData( integer const ip, array1d< array1d< real64 > > const & tableValues ); - /** - * @brief Read a table from file and check its row length - * @param[in] fileName the name of the file - * @param[in] minRowLength the expected minimum row length (typically 3: pressure, density, viscosity) - * @param[out] data the data from the table - */ - void - readTable( string const & fileName, - integer minRowLength, - array1d< array1d< real64 > > & data ); - - /** * @brief Check the monotonicity of the PVT relationship */ From b23c33de97d519c1cb890510ac095da82b49d38e Mon Sep 17 00:00:00 2001 From: DENEL Bertrand Date: Fri, 6 Dec 2024 12:53:26 -0600 Subject: [PATCH 068/102] Addressed Pavel's comments. --- .../fluidFlow/ImmiscibleMultiphaseFlow.cpp | 102 +++++++++++++++++- .../fluidFlow/ImmiscibleMultiphaseFlow.hpp | 27 ++++- .../ImmiscibleMultiphaseKernels.hpp | 44 +++++--- 3 files changed, 152 insertions(+), 21 deletions(-) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp index e44069772f7..bc667776612 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp @@ -67,6 +67,22 @@ ImmiscibleMultiphaseFlow::ImmiscibleMultiphaseFlow( const string & name, setInputFlag( InputFlags::OPTIONAL ). setApplyDefaultValue( 1 ). setDescription( "Flag indicating whether total mass equation is used" ); + + this->registerWrapper( viewKeyStruct::solutionChangeScalingFactorString(), &m_solutionChangeScalingFactor ). + setSizedFromParent( 0 ). + setInputFlag( InputFlags::OPTIONAL ). + setApplyDefaultValue( 0.5 ). + setDescription( "Damping factor for solution change targets" ); + this->registerWrapper( viewKeyStruct::targetRelativePresChangeString(), &m_targetRelativePresChange ). + setSizedFromParent( 0 ). + setInputFlag( InputFlags::OPTIONAL ). + setApplyDefaultValue( 0.2 ). + setDescription( "Target (relative) change in pressure in a time step (expected value between 0 and 1)" ); + this->registerWrapper( viewKeyStruct::targetPhaseVolFracChangeString(), &m_targetPhaseVolFracChange ). + setSizedFromParent( 0 ). + setInputFlag( InputFlags::OPTIONAL ). + setApplyDefaultValue( 0.2 ). + setDescription( "Target (absolute) change in phase volume fraction in a time step" ); } void ImmiscibleMultiphaseFlow::postInputInitialization() @@ -288,7 +304,7 @@ void ImmiscibleMultiphaseFlow::updateFluidState( ElementSubRegionBase & subRegio GEOS_MARK_FUNCTION; updateFluidModel( subRegion ); - updatePhaseVolumeFraction( subRegion ); + updateVolumeConstraint( subRegion ); updatePhaseMass( subRegion ); updateRelPermModel( subRegion ); updatePhaseMobility( subRegion ); @@ -401,7 +417,7 @@ void ImmiscibleMultiphaseFlow::initializeFluidState( MeshLevel & mesh, // Also, initialize the fluid model // // Note: - // - This must be called after updatePhaseVolumeFraction + // - This must be called after updateVolumeConstraint // - This step depends on phaseVolFraction // initialized phase volume fraction @@ -533,7 +549,7 @@ ImmiscibleMultiphaseFlow::implicitStepSetup( real64 const & GEOS_UNUSED_PARAM( t // update porosity, permeability updatePorosityAndPermeability( subRegion ); // update all fluid properties - updatePhaseVolumeFraction( subRegion ); + updateVolumeConstraint( subRegion ); updateFluidState( subRegion ); // after the update, save the new saturation @@ -1107,7 +1123,7 @@ void ImmiscibleMultiphaseFlow::applySystemSolution( DofManager const & dofManage } -void ImmiscibleMultiphaseFlow::updatePhaseVolumeFraction( ElementSubRegionBase & subRegion ) const +void ImmiscibleMultiphaseFlow::updateVolumeConstraint( ElementSubRegionBase & subRegion ) const { GEOS_MARK_FUNCTION; @@ -1261,12 +1277,88 @@ void ImmiscibleMultiphaseFlow::updateState( DomainPartition & domain ) // update porosity, permeability, and solid internal energy updatePorosityAndPermeability( subRegion ); // update all fluid properties - updatePhaseVolumeFraction( subRegion ); + updateVolumeConstraint( subRegion ); updateFluidState( subRegion ); } ); } ); } +real64 ImmiscibleMultiphaseFlow::setNextDtBasedOnStateChange( real64 const & currentDt, + DomainPartition & domain ) +{ + if( m_targetRelativePresChange >= 1.0 && + m_targetPhaseVolFracChange >= 1.0 ) + { + return LvArray::NumericLimits< real64 >::max; + } + + real64 maxRelativePresChange = 0.0; + real64 maxAbsolutePhaseVolFracChange = 0.0; + + integer const numPhase = m_numPhases; + + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, + MeshLevel & mesh, + arrayView1d< string const > const & regionNames ) + { + mesh.getElemManager().forElementSubRegions( regionNames, + [&]( localIndex const, + ElementSubRegionBase & subRegion ) + { + arrayView1d< integer const > const ghostRank = subRegion.ghostRank(); + + arrayView1d< real64 const > const pres = subRegion.getField< fields::flow::pressure >(); + arrayView1d< real64 const > const pres_n = subRegion.getField< fields::flow::pressure_n >(); + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFrac = + subRegion.getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); + arrayView2d< real64, immiscibleFlow::USD_PHASE > const phaseVolFrac_n = + subRegion.getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction_n >(); + + RAJA::ReduceMax< parallelDeviceReduce, real64 > subRegionMaxPresChange( 0.0 ); + RAJA::ReduceMax< parallelDeviceReduce, real64 > subRegionMaxPhaseVolFracChange( 0.0 ); + + forAll< parallelDevicePolicy<> >( subRegion.size(), [=] GEOS_HOST_DEVICE ( localIndex const ei ) + { + if( ghostRank[ei] < 0 ) + { + // switch from relative to absolute when values less than 1 + subRegionMaxPresChange.max( LvArray::math::abs( pres[ei] - pres_n[ei] ) / LvArray::math::max( LvArray::math::abs( pres_n[ei] ), 1.0 ) ); + for( integer ip = 0; ip < numPhase; ++ip ) + { + subRegionMaxPhaseVolFracChange.max( LvArray::math::abs( phaseVolFrac[ei][ip] - phaseVolFrac_n[ei][ip] ) ); + } + } + } ); + + maxRelativePresChange = LvArray::math::max( maxRelativePresChange, subRegionMaxPresChange.get() ); + maxAbsolutePhaseVolFracChange = LvArray::math::max( maxAbsolutePhaseVolFracChange, subRegionMaxPhaseVolFracChange.get() ); + + } ); + } ); + + maxRelativePresChange = MpiWrapper::max( maxRelativePresChange ); + maxAbsolutePhaseVolFracChange = MpiWrapper::max( maxAbsolutePhaseVolFracChange ); + + GEOS_LOG_LEVEL_INFO_RANK_0( logInfo::TimeStep, GEOS_FMT( "{}: max relative pressure change during time step = {} %", + getName(), GEOS_FMT( "{:.{}f}", 100*maxRelativePresChange, 3 ) ) ); + GEOS_LOG_LEVEL_INFO_RANK_0( logInfo::TimeStep, GEOS_FMT( "{}: max absolute phase volume fraction change during time step = {}", + getName(), GEOS_FMT( "{:.{}f}", maxAbsolutePhaseVolFracChange, 3 ) ) ); + + real64 const eps = LvArray::NumericLimits< real64 >::epsilon; + + real64 const nextDtPressure = currentDt * ( 1.0 + m_solutionChangeScalingFactor ) * m_targetRelativePresChange + / std::max( eps, maxRelativePresChange + m_solutionChangeScalingFactor * m_targetRelativePresChange ); + if( m_nonlinearSolverParameters.getLogLevel() > 0 ) + GEOS_LOG_RANK_0( GEOS_FMT( "{}: next time step based on pressure change = {}", getName(), nextDtPressure )); + real64 const nextDtPhaseVolFrac = currentDt * ( 1.0 + m_solutionChangeScalingFactor ) * m_targetPhaseVolFracChange + / std::max( eps, maxAbsolutePhaseVolFracChange + m_solutionChangeScalingFactor * m_targetPhaseVolFracChange ); + if( m_nonlinearSolverParameters.getLogLevel() > 0 ) + GEOS_LOG_RANK_0( GEOS_FMT( "{}: next time step based on phase volume fraction change = {}", getName(), nextDtPhaseVolFrac )); + + return std::min( nextDtPressure, nextDtPhaseVolFrac ); + +} + real64 ImmiscibleMultiphaseFlow::setNextDt( const geos::real64 & currentDt, geos::DomainPartition & domain ) { return PhysicsSolverBase::setNextDt( currentDt, domain ); diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp index 142c7e9cdf9..c8a072eb58b 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp @@ -125,7 +125,7 @@ class ImmiscibleMultiphaseFlow : public FlowSolverBase void updateFluidState( ElementSubRegionBase & subRegion ) const; - void updatePhaseVolumeFraction( ElementSubRegionBase & subRegion ) const; + void updateVolumeConstraint( ElementSubRegionBase & subRegion ) const; virtual void saveConvergedState( ElementSubRegionBase & subRegion ) const override final; @@ -204,8 +204,12 @@ class ImmiscibleMultiphaseFlow : public FlowSolverBase * @param[in] domain the domain object * @return the prescribed time step size */ - real64 setNextDt( real64 const & currentDt, - DomainPartition & domain ) override; + + virtual real64 setNextDtBasedOnStateChange( real64 const & currentDt, + DomainPartition & domain ) override; + + real64 setNextDt( real64 const & currentDt, + DomainPartition & domain ) override; virtual void initializePostInitialConditionsPreSubGroups() override; @@ -217,9 +221,18 @@ class ImmiscibleMultiphaseFlow : public FlowSolverBase struct viewKeyStruct : public FlowSolverBase::viewKeyStruct { + // inputs static constexpr char const * capPressureNamesString() { return "capPressureNames"; } static constexpr char const * relPermNamesString() { return "relPermNames"; } static constexpr char const * elemDofFieldString() { return "elemDofField"; } + + // time stepping controls + static constexpr char const * solutionChangeScalingFactorString() { return "solutionChangeScalingFactor"; } + static constexpr char const * targetRelativePresChangeString() { return "targetRelativePressureChangeInTimeStep"; } + static constexpr char const * targetPhaseVolFracChangeString() { return "targetPhaseVolFractionChangeInTimeStep"; } + + // nonlinear solver parameters + static constexpr char const * maxRelativePresChangeString() { return "maxRelativePressureChange"; } static constexpr char const * useTotalMassEquationString() { return "useTotalMassEquation"; } }; @@ -280,6 +293,14 @@ class ImmiscibleMultiphaseFlow : public FlowSolverBase /// flag to determine whether or not to use total velocity formulation integer m_useTotalMassEquation; + /// target (relative) change in pressure in a time step + real64 m_targetRelativePresChange; + + /// target (absolute) change in phase volume fraction in a time step + real64 m_targetPhaseVolFracChange; + + /// damping factor for solution change targets + real64 m_solutionChangeScalingFactor; private: diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp index 30ccd2bafee..582cb139ef0 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp @@ -78,6 +78,7 @@ class FaceBasedAssemblyKernelBase StencilAccessors< fields::ghostRank, fields::flow::pressure, fields::flow::gravityCoefficient, + fields::immiscibleMultiphaseFlow::phaseVolumeFraction, fields::immiscibleMultiphaseFlow::phaseMobility, fields::immiscibleMultiphaseFlow::dPhaseMobility >; @@ -134,6 +135,7 @@ class FaceBasedAssemblyKernelBase m_ghostRank( multiPhaseFlowAccessors.get( fields::ghostRank {} ) ), m_gravCoef( multiPhaseFlowAccessors.get( fields::flow::gravityCoefficient {} ) ), m_pres( multiPhaseFlowAccessors.get( fields::flow::pressure {} ) ), + m_phaseVolFrac( multiPhaseFlowAccessors.get( fields::immiscibleMultiphaseFlow::phaseVolumeFraction {} ) ), m_mob( multiPhaseFlowAccessors.get( fields::immiscibleMultiphaseFlow::phaseMobility {} ) ), m_dMob( multiPhaseFlowAccessors.get( fields::immiscibleMultiphaseFlow::dPhaseMobility {} ) ), m_dens( fluidAccessors.get( fields::twophasefluid::phaseDensity {} ) ), @@ -169,8 +171,9 @@ class FaceBasedAssemblyKernelBase ElementViewConst< arrayView1d< real64 const > > const m_gravCoef; // Primary and secondary variables - /// Views on pressure + /// Views on pressure and phase volume fraction ElementViewConst< arrayView1d< real64 const > > const m_pres; + ElementViewConst< arrayView2d< real64 const, immiscibleFlow::USD_PHASE > > const m_phaseVolFrac; /// Views on fluid mobility ElementViewConst< arrayView2d< real64 const, immiscibleFlow::USD_PHASE > > const m_mob; @@ -421,15 +424,33 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase for( integer ip = 0; ip < m_numPhases; ++ip ) { // calculate quantities on primary connected cells + integer denom = 0; for( integer ke = 0; ke < 2; ++ke ) { // density - real64 const density = m_dens[seri[ke]][sesri[ke]][sei[ke]][0][ip]; // r = rho1 || rho2 + bool const phaseExists = (m_phaseVolFrac[seri[ke]][sesri[ke]][sei[ke]][ip] > 0); + if( !phaseExists ) + { + continue; + } + + real64 const density = m_dens[seri[ke]][sesri[ke]][sei[ke]][0][ip]; // r = rho1 || rho2 real64 const dDens_dP = m_dDens_dPres[seri[ke]][sesri[ke]][sei[ke]][0][ip][Deriv::dP]; // dr/dP = dr1/dP1 || dr2/dP // average density and derivatives - densMean[ip] += 0.5 * density; // rho = (rho1 + rho2) / 2 - dDensMean_dP[ip][ke] = 0.5 * dDens_dP; // drho/dP = { (dr1/dP1)/2 , (dr2/dP2)/2 } + densMean[ip] += density; // rho = (rho1 + rho2) + dDensMean_dP[ip][ke] = dDens_dP; // drho/dP = { (dr1/dP1) , (dr2/dP2) } + + denom++; + } + + if( denom > 1 ) + { + densMean[ip] /= denom; // rho = (rho1 + rho2) / denom + for( integer ke = 0; ke < 2; ++ke ) + { + dDensMean_dP[ip][ke] /= denom; // drho/dP = { (dr1/dP1) / denom , (dr2/dP2) / denom } + } } //***** calculation of flux ***** @@ -439,7 +460,7 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase real64 dPresGrad_dTrans = 0.0; real64 dGravHead_dTrans = 0.0; real64 dCapGrad_dTrans = 0.0; - int signPotDiff[2] = {1, -1}; + constexpr int signPotDiff[2] = {1, -1}; for( integer ke = 0; ke < 2; ++ke ) { @@ -903,17 +924,14 @@ class AccumulationKernel /** * @brief Compute the local accumulation contributions to the residual and Jacobian - * @tparam FUNC the type of the function that can be used to customize the kernel * @param[in] ei the element index * @param[inout] stack the stack variables */ - template< typename FUNC = NoOpFunc > GEOS_HOST_DEVICE void computeAccumulation( localIndex const ei, - StackVariables & stack, - FUNC = NoOpFunc{} ) const + StackVariables & stack ) const { - int signPotDiff[2] = {1, -1}; + constexpr int sign[2] = {1, -1}; // ip - index of phase/component whose conservation equation is assembled // (i.e. row number in local matrix) for( integer ip = 0; ip < m_numPhases; ++ip ) @@ -928,9 +946,8 @@ class AccumulationKernel stack.localJacobian[ip][0] += dPhaseMass_dP; real64 const dPhaseMass_dS = stack.poreVolume * m_phaseDens[ei][0][ip]; - stack.localJacobian[ip][1] += signPotDiff[ip] * dPhaseMass_dS; + stack.localJacobian[ip][1] += sign[ip] * dPhaseMass_dS; } - } /** @@ -1153,7 +1170,7 @@ class PhaseMobilityKernel arraySlice1d< real64, immiscibleFlow::USD_PHASE - 1 > const phaseMob = m_phaseMob[ei]; arraySlice2d< real64, immiscibleFlow::USD_PHASE_DS - 1 > const dPhaseMob = m_dPhaseMob[ei]; - int sign[2] = {1, -1}; + constexpr int sign[2] = {1, -1}; for( integer ip = 0; ip < numPhase; ++ip ) { @@ -1171,6 +1188,7 @@ class PhaseMobilityKernel // for( integer jp = 0; jp < numPhase-1; ++jp ) // { + // Derivative matrix is currently diagonal. Implementation below handles missing off-diagonal entry. real64 const dRelPerm_dS = sign[ip] * m_dPhaseRelPerm_dPhaseVolFrac[ei][0][ip][ip]; dPhaseMob[ip][Deriv::dS] = dRelPerm_dS * density / viscosity; // } From 557b179d093f1e876471fb8c27dc69735132d956 Mon Sep 17 00:00:00 2001 From: Pavel Tomin Date: Sat, 7 Dec 2024 10:51:41 -0600 Subject: [PATCH 069/102] code style --- .../physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp index c8a072eb58b..3698fc0a904 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp @@ -206,10 +206,10 @@ class ImmiscibleMultiphaseFlow : public FlowSolverBase */ virtual real64 setNextDtBasedOnStateChange( real64 const & currentDt, - DomainPartition & domain ) override; + DomainPartition & domain ) override; - real64 setNextDt( real64 const & currentDt, - DomainPartition & domain ) override; + real64 setNextDt( real64 const & currentDt, + DomainPartition & domain ) override; virtual void initializePostInitialConditionsPreSubGroups() override; From 3cef9abfc03f0edb53f9a1f7b5e71e225c3ca1b9 Mon Sep 17 00:00:00 2001 From: DENEL Bertrand Date: Mon, 9 Dec 2024 19:06:34 -0600 Subject: [PATCH 070/102] Used the newly introduced initializeState from FlowSolverBase. --- .../mgrStrategies/ImmiscibleMultiphaseFVM.hpp | 5 --- .../fluidFlow/ImmiscibleMultiphaseFlow.cpp | 37 ++----------------- .../fluidFlow/ImmiscibleMultiphaseFlow.hpp | 16 +++----- 3 files changed, 8 insertions(+), 50 deletions(-) diff --git a/src/coreComponents/linearAlgebra/interfaces/hypre/mgrStrategies/ImmiscibleMultiphaseFVM.hpp b/src/coreComponents/linearAlgebra/interfaces/hypre/mgrStrategies/ImmiscibleMultiphaseFVM.hpp index 3f05ac5987a..21239def26e 100644 --- a/src/coreComponents/linearAlgebra/interfaces/hypre/mgrStrategies/ImmiscibleMultiphaseFVM.hpp +++ b/src/coreComponents/linearAlgebra/interfaces/hypre/mgrStrategies/ImmiscibleMultiphaseFVM.hpp @@ -55,11 +55,6 @@ class ImmiscibleMultiphaseFVM : public MGRStrategyBase< 1 > explicit ImmiscibleMultiphaseFVM( arrayView1d< int const > const & numComponentsPerField ) : MGRStrategyBase( LvArray::integerConversion< HYPRE_Int >( numComponentsPerField[0] ) ) { - // Level 0: eliminate last density which corresponds to the volume constraint equation - // m_labels[0].resize( m_numBlocks - 1 ); - // std::iota( m_labels[0].begin(), m_labels[0].end(), 0 ); - - // Level 0: eliminate the phase volume fractions m_labels[0].push_back( 0 ); setupLabels(); diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp index bc667776612..d610b2e39fb 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp @@ -363,7 +363,6 @@ void ImmiscibleMultiphaseFlow::updatePhaseMobility( ObjectManagerBase & dataGrou } void ImmiscibleMultiphaseFlow::initializeFluidState( MeshLevel & mesh, - DomainPartition & GEOS_UNUSED_PARAM( domain ), arrayView1d< string const > const & regionNames ) { GEOS_MARK_FUNCTION; @@ -477,6 +476,7 @@ void ImmiscibleMultiphaseFlow::initializeFluidState( MeshLevel & mesh, } ); } + void ImmiscibleMultiphaseFlow::initializePostInitialConditionsPreSubGroups() { GEOS_MARK_FUNCTION; @@ -495,41 +495,12 @@ void ImmiscibleMultiphaseFlow::initializePostInitialConditionsPreSubGroups() regionNames ); CommunicationTools::getInstance().synchronizeFields( fieldsToBeSync, mesh, domain.getNeighbors(), false ); - - mesh.getElemManager().forElementSubRegions< CellElementSubRegion, SurfaceElementSubRegion >( regionNames, - [&]( localIndex const, - auto & subRegion ) - { - saveConvergedState( subRegion ); // necessary for a meaningful porosity update in sequential schemes - updatePorosityAndPermeability( subRegion ); - - CoupledSolidBase const & porousSolid = - getConstitutiveModel< CoupledSolidBase >( subRegion, - subRegion.template getReference< string >( viewKeyStruct::solidNamesString() ) ); - porousSolid.initializeState(); - } ); - - // Initialize primary variables from applied initial conditions - initializeFluidState( mesh, domain, regionNames ); - - mesh.getElemManager().forElementRegions< SurfaceElementRegion >( regionNames, - [&]( localIndex const, - SurfaceElementRegion & region ) - { - region.forElementSubRegions< FaceElementSubRegion >( [&]( FaceElementSubRegion & subRegion ) - { - subRegion.getWrapper< real64_array >( fields::flow::hydraulicAperture::key() ). - setApplyDefaultValue( region.getDefaultAperture() ); - } ); - } ); - } ); - // report to the user if some pore volumes are very small - // note: this function is here because: 1) porosity has been initialized and 2) NTG has been applied - validatePoreVolumes( domain ); + initializeState( domain ); } + void ImmiscibleMultiphaseFlow::implicitStepSetup( real64 const & GEOS_UNUSED_PARAM( time_n ), real64 const & GEOS_UNUSED_PARAM( dt ), @@ -632,8 +603,6 @@ void ImmiscibleMultiphaseFlow::assembleAccumulationTerm( DomainPartition & domai } ); } ); - - } void ImmiscibleMultiphaseFlow::assembleFluxTerms( real64 const dt, diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp index 3698fc0a904..054388fb35c 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp @@ -166,15 +166,6 @@ class ImmiscibleMultiphaseFlow : public FlowSolverBase DofManager const & dofManager, CRSMatrixView< real64, globalIndex const > const & localMatrix, arrayView1d< real64 > const & localRhs ) const; - /** - * @brief Initialize all variables from initial conditions - * @param domain the domain containing the mesh and fields - * - * Initialize all variables from initial conditions. This calculating primary variable values - * from prescribed intermediate values (i.e. global densities from global fractions) - * and any applicable hydrostatic equilibration of the domain - */ - void initializeFluidState( MeshLevel & mesh, DomainPartition & domain, arrayView1d< string const > const & regionNames ); /** * @brief Function to perform the Application of Dirichlet type BC's @@ -211,8 +202,13 @@ class ImmiscibleMultiphaseFlow : public FlowSolverBase real64 setNextDt( real64 const & currentDt, DomainPartition & domain ) override; + virtual void initializePreSubGroups() override; + virtual void initializePostInitialConditionsPreSubGroups() override; + virtual void initializeFluidState( MeshLevel & mesh, arrayView1d< string const > const & regionNames ) override; + + /** * @brief Function to update fluid mass * @param subRegion subregion that contains the fields @@ -241,8 +237,6 @@ class ImmiscibleMultiphaseFlow : public FlowSolverBase virtual void postInputInitialization() override; - virtual void initializePreSubGroups() override; - /** * @brief Update all relevant fluid models using current values of pressure and phase volume fraction * @param dataGroup the group storing the required fields From 8bb5ba63d0b656ff8d68f0b1d8a478c9bd979d46 Mon Sep 17 00:00:00 2001 From: DENEL Bertrand Date: Mon, 9 Dec 2024 19:09:18 -0600 Subject: [PATCH 071/102] Fixed style. --- .../physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp index d610b2e39fb..c80d31ea74d 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp @@ -497,7 +497,7 @@ void ImmiscibleMultiphaseFlow::initializePostInitialConditionsPreSubGroups() CommunicationTools::getInstance().synchronizeFields( fieldsToBeSync, mesh, domain.getNeighbors(), false ); } ); - initializeState( domain ); + initializeState( domain ); } From 3ddd347c31a13942031952ada2f5c64aa3b7a7be Mon Sep 17 00:00:00 2001 From: DENEL Bertrand Date: Tue, 10 Dec 2024 12:29:04 -0600 Subject: [PATCH 072/102] Changed Total S.A. --- .../hypre/mgrStrategies/ImmiscibleMultiphaseFVM.hpp | 2 +- .../physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp | 2 +- .../physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp | 2 +- .../fluidFlow/ImmiscibleMultiphaseFlowFields.hpp | 2 +- .../immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp | 2 +- .../kernels/immiscibleMultiphase/KernelLaunchSelectors.hpp | 6 +----- .../unitTests/constitutiveTests/testTwoPhaseFluid.cpp | 2 +- .../fluidFlowTests/testImmiscibleMultiphaseFlow.cpp | 2 +- 8 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/coreComponents/linearAlgebra/interfaces/hypre/mgrStrategies/ImmiscibleMultiphaseFVM.hpp b/src/coreComponents/linearAlgebra/interfaces/hypre/mgrStrategies/ImmiscibleMultiphaseFVM.hpp index 21239def26e..da7ef1409f9 100644 --- a/src/coreComponents/linearAlgebra/interfaces/hypre/mgrStrategies/ImmiscibleMultiphaseFVM.hpp +++ b/src/coreComponents/linearAlgebra/interfaces/hypre/mgrStrategies/ImmiscibleMultiphaseFVM.hpp @@ -3,7 +3,7 @@ * SPDX-License-Identifier: LGPL-2.1-only * * Copyright (c) 2016-2024 Lawrence Livermore National Security LLC - * Copyright (c) 2018-2024 Total, S.A + * Copyright (c) 2018-2024 TotalEnergies * Copyright (c) 2018-2024 The Board of Trustees of the Leland Stanford Junior University * Copyright (c) 2023-2024 Chevron * Copyright (c) 2019- GEOS/GEOSX Contributors diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp index c80d31ea74d..fb68e47ef0b 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp @@ -3,7 +3,7 @@ * SPDX-License-Identifier: LGPL-2.1-only * * Copyright (c) 2016-2024 Lawrence Livermore National Security LLC - * Copyright (c) 2018-2024 Total, S.A + * Copyright (c) 2018-2024 TotalEnergies * Copyright (c) 2018-2024 The Board of Trustees of the Leland Stanford Junior University * Copyright (c) 2023-2024 Chevron * Copyright (c) 2019- GEOS/GEOSX Contributors diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp index 054388fb35c..c1037070526 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp @@ -3,7 +3,7 @@ * SPDX-License-Identifier: LGPL-2.1-only * * Copyright (c) 2016-2024 Lawrence Livermore National Security LLC - * Copyright (c) 2018-2024 Total, S.A + * Copyright (c) 2018-2024 TotalEnergies * Copyright (c) 2018-2024 The Board of Trustees of the Leland Stanford Junior University * Copyright (c) 2023-2024 Chevron * Copyright (c) 2019- GEOS/GEOSX Contributors diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlowFields.hpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlowFields.hpp index 48d560815d9..17fdb8f04ee 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlowFields.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlowFields.hpp @@ -3,7 +3,7 @@ * SPDX-License-Identifier: LGPL-2.1-only * * Copyright (c) 2016-2024 Lawrence Livermore National Security LLC - * Copyright (c) 2018-2024 Total, S.A + * Copyright (c) 2018-2024 TotalEnergies * Copyright (c) 2018-2024 The Board of Trustees of the Leland Stanford Junior University * Copyright (c) 2023-2024 Chevron * Copyright (c) 2019- GEOS/GEOSX Contributors diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp index 582cb139ef0..a1b1bcd56b1 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp @@ -3,7 +3,7 @@ * SPDX-License-Identifier: LGPL-2.1-only * * Copyright (c) 2016-2024 Lawrence Livermore National Security LLC - * Copyright (c) 2018-2024 Total, S.A + * Copyright (c) 2018-2024 TotalEnergies * Copyright (c) 2018-2024 The Board of Trustees of the Leland Stanford Junior University * Copyright (c) 2023-2024 Chevron * Copyright (c) 2019- GEOS/GEOSX Contributors diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/KernelLaunchSelectors.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/KernelLaunchSelectors.hpp index f1548bb2c7e..f219c31382a 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/KernelLaunchSelectors.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/KernelLaunchSelectors.hpp @@ -3,7 +3,7 @@ * SPDX-License-Identifier: LGPL-2.1-only * * Copyright (c) 2016-2024 Lawrence Livermore National Security LLC - * Copyright (c) 2018-2024 Total, S.A + * Copyright (c) 2018-2024 TotalEnergies * Copyright (c) 2018-2024 The Board of Trustees of the Leland Stanford Junior University * Copyright (c) 2023-2024 Chevron * Copyright (c) 2019- GEOS/GEOSX Contributors @@ -20,10 +20,6 @@ #ifndef GEOS_PHYSICSSOLVERS_FLUIDFLOW_IMMISCIBLE_KERNELLAUNCHSELECTOR_HPP #define GEOS_PHYSICSSOLVERS_FLUIDFLOW_IMMISCIBLE_KERNELLAUNCHSELECTOR_HPP -//#include "codingUtilities/Utilities.hpp" -//#include "common/DataLayouts.hpp" -//#include "common/DataTypes.hpp" -//#include "common/GEOS_RAJA_Interface.hpp" namespace geos { diff --git a/src/coreComponents/unitTests/constitutiveTests/testTwoPhaseFluid.cpp b/src/coreComponents/unitTests/constitutiveTests/testTwoPhaseFluid.cpp index b37fc732a55..b456b3468bb 100644 --- a/src/coreComponents/unitTests/constitutiveTests/testTwoPhaseFluid.cpp +++ b/src/coreComponents/unitTests/constitutiveTests/testTwoPhaseFluid.cpp @@ -3,7 +3,7 @@ * SPDX-License-Identifier: LGPL-2.1-only * * Copyright (c) 2016-2024 Lawrence Livermore National Security LLC - * Copyright (c) 2018-2024 Total, S.A + * Copyright (c) 2018-2024 TotalEnergies * Copyright (c) 2018-2024 The Board of Trustees of the Leland Stanford Junior University * Copyright (c) 2023-2024 Chevron * Copyright (c) 2019- GEOS/GEOSX Contributors diff --git a/src/coreComponents/unitTests/fluidFlowTests/testImmiscibleMultiphaseFlow.cpp b/src/coreComponents/unitTests/fluidFlowTests/testImmiscibleMultiphaseFlow.cpp index a1fc731b321..d86be36ea17 100644 --- a/src/coreComponents/unitTests/fluidFlowTests/testImmiscibleMultiphaseFlow.cpp +++ b/src/coreComponents/unitTests/fluidFlowTests/testImmiscibleMultiphaseFlow.cpp @@ -3,7 +3,7 @@ * SPDX-License-Identifier: LGPL-2.1-only * * Copyright (c) 2016-2024 Lawrence Livermore National Security LLC - * Copyright (c) 2018-2024 Total, S.A + * Copyright (c) 2018-2024 TotalEnergies * Copyright (c) 2018-2024 The Board of Trustees of the Leland Stanford Junior University * Copyright (c) 2023-2024 Chevron * Copyright (c) 2019- GEOS/GEOSX Contributors From 8d0cd414fd934fc79fcf078cc6e804600118e1b1 Mon Sep 17 00:00:00 2001 From: DENEL Bertrand Date: Tue, 10 Dec 2024 16:41:30 -0600 Subject: [PATCH 073/102] Made density averaging optional (need gpu validation). --- .../fluidFlow/ImmiscibleMultiphaseFlow.cpp | 7 +++++ .../fluidFlow/ImmiscibleMultiphaseFlow.hpp | 27 +++++++++++++++++++ .../ImmiscibleMultiphaseKernels.hpp | 19 ++++++++----- 3 files changed, 47 insertions(+), 6 deletions(-) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp index fb68e47ef0b..8a43a9218ce 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp @@ -68,6 +68,12 @@ ImmiscibleMultiphaseFlow::ImmiscibleMultiphaseFlow( const string & name, setApplyDefaultValue( 1 ). setDescription( "Flag indicating whether total mass equation is used" ); + this->registerWrapper( viewKeyStruct::gravityDensitySchemeString(), &m_gravityDensityScheme ). + setSizedFromParent( 0 ). + setInputFlag( InputFlags::OPTIONAL ). + setApplyDefaultValue( GravityDensityScheme::ArithmeticAverage ). + setDescription( "Scheme for density treatment in gravity" ); + this->registerWrapper( viewKeyStruct::solutionChangeScalingFactorString(), &m_solutionChangeScalingFactor ). setSizedFromParent( 0 ). setInputFlag( InputFlags::OPTIONAL ). @@ -632,6 +638,7 @@ void ImmiscibleMultiphaseFlow::assembleFluxTerms( real64 const dt, dofKey, m_hasCapPressure, m_useTotalMassEquation, + m_gravityDensityScheme == GravityDensityScheme::PhasePresence, getName(), mesh.getElemManager(), stencilWrapper, diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp index c1037070526..4d6ccbd8b21 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp @@ -27,6 +27,27 @@ namespace geos { +/** + * @brief Options for density treatment in gravity + */ +enum class GravityDensityScheme : integer +{ + ArithmeticAverage, ///< average phase density is computed using simple arithmetic average: + /// rho_ave = 0.5 * (rho_i + rho_j) + PhasePresence, ///< average phase density is computed using checking for phase presence: + /// rho_ave = 0.5 * (rho_i + rho_j) if phase is present in both cells i and j + /// = rho_i if phase is present in only cell i + /// = rho_j if phase is present in only cell j +}; + +/** + * @brief Strings for options for density treatment in gravity + */ +ENUM_STRINGS( GravityDensityScheme, + "ArithmeticAverage", + "PhasePresence" ); + + //START_SPHINX_INCLUDE_00 /** * @class ImmiscibleMultiphaseFlow @@ -222,6 +243,9 @@ class ImmiscibleMultiphaseFlow : public FlowSolverBase static constexpr char const * relPermNamesString() { return "relPermNames"; } static constexpr char const * elemDofFieldString() { return "elemDofField"; } + // density averaging scheme + static constexpr char const * gravityDensitySchemeString() { return "gravityDensityScheme"; } + // time stepping controls static constexpr char const * solutionChangeScalingFactorString() { return "solutionChangeScalingFactor"; } static constexpr char const * targetRelativePresChangeString() { return "targetRelativePressureChangeInTimeStep"; } @@ -287,6 +311,9 @@ class ImmiscibleMultiphaseFlow : public FlowSolverBase /// flag to determine whether or not to use total velocity formulation integer m_useTotalMassEquation; + /// scheme for density treatment in gravity + GravityDensityScheme m_gravityDensityScheme; + /// target (relative) change in pressure in a time step real64 m_targetRelativePresChange; diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp index a1b1bcd56b1..0f2e4045be4 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp @@ -125,7 +125,8 @@ class FaceBasedAssemblyKernelBase CRSMatrixView< real64, globalIndex const > const & localMatrix, arrayView1d< real64 > const & localRhs, integer const hasCapPressure, - integer const useTotalMassEquation ) + integer const useTotalMassEquation, + integer const checkPhasePresenceInGravity ) : m_numPhases ( numPhases ), m_rankOffset( rankOffset ), m_dt( dt ), @@ -145,7 +146,8 @@ class FaceBasedAssemblyKernelBase m_localMatrix( localMatrix ), m_localRhs( localRhs ), m_hasCapPressure ( hasCapPressure ), - m_useTotalMassEquation ( useTotalMassEquation ) + m_useTotalMassEquation ( useTotalMassEquation ), + m_checkPhasePresenceInGravity ( checkPhasePresenceInGravity ) {} protected: @@ -197,6 +199,7 @@ class FaceBasedAssemblyKernelBase // Flags integer const m_hasCapPressure; integer const m_useTotalMassEquation; + integer const m_checkPhasePresenceInGravity; }; /***************************************** */ @@ -255,7 +258,8 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase CRSMatrixView< real64, globalIndex const > const & localMatrix, arrayView1d< real64 > const & localRhs, integer const hasCapPressure, - integer const useTotalMassEquation ) + integer const useTotalMassEquation, + integer const checkPhasePresenceInGravity ) : FaceBasedAssemblyKernelBase( numPhases, rankOffset, dofNumberAccessor, @@ -267,7 +271,8 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase localMatrix, localRhs, hasCapPressure, - useTotalMassEquation ), + useTotalMassEquation, + checkPhasePresenceInGravity ), m_stencilWrapper( stencilWrapper ), m_seri( stencilWrapper.getElementRegionIndices() ), m_sesri( stencilWrapper.getElementSubRegionIndices() ), @@ -429,7 +434,7 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase { // density bool const phaseExists = (m_phaseVolFrac[seri[ke]][sesri[ke]][sei[ke]][ip] > 0); - if( !phaseExists ) + if( m_checkPhasePresenceInGravity && !phaseExists ) { continue; } @@ -758,6 +763,7 @@ class FaceBasedAssemblyKernelFactory string const & dofKey, integer const hasCapPressure, integer const useTotalMassEquation, + integer const checkPhasePresenceInGravity, string const & solverName, ElementRegionManager const & elemManager, STENCILWRAPPER const & stencilWrapper, @@ -780,7 +786,8 @@ class FaceBasedAssemblyKernelFactory kernelType kernel( numPhases, rankOffset, stencilWrapper, dofNumberAccessor, flowAccessors, fluidAccessors, capPressureAccessors, permAccessors, - dt, localMatrix, localRhs, hasCapPressure, useTotalMassEquation ); + dt, localMatrix, localRhs, hasCapPressure, useTotalMassEquation, + checkPhasePresenceInGravity ); kernelType::template launch< POLICY >( stencilWrapper.size(), kernel ); } }; From f39620c1354b6ef37020b887cc08018a74137e33 Mon Sep 17 00:00:00 2001 From: DENEL Bertrand Date: Wed, 11 Dec 2024 19:32:12 -0600 Subject: [PATCH 074/102] Added schema. --- src/coreComponents/schema/schema.xsd | 86 ++++++++++- src/coreComponents/schema/schema.xsd.other | 163 ++++++++++++--------- 2 files changed, 178 insertions(+), 71 deletions(-) diff --git a/src/coreComponents/schema/schema.xsd b/src/coreComponents/schema/schema.xsd index e130b1e56d4..101588f0552 100644 --- a/src/coreComponents/schema/schema.xsd +++ b/src/coreComponents/schema/schema.xsd @@ -371,6 +371,10 @@ + + + + @@ -887,6 +891,10 @@ + + + + @@ -2284,6 +2292,7 @@ Level 0 outputs no specific information for this solver. Higher levels require m + @@ -3245,7 +3254,7 @@ Level 0 outputs no specific information for this solver. Higher levels require m - + @@ -3268,11 +3277,69 @@ Local- Add jump stabilization on interior of macro elements--> - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -5065,6 +5132,7 @@ Level 0 outputs no specific information for this solver. Higher levels require m + @@ -6524,6 +6592,20 @@ To neglect hysteresis on this phase, just use the same table name for the draina + + + + + + + + + + + + diff --git a/src/coreComponents/schema/schema.xsd.other b/src/coreComponents/schema/schema.xsd.other index 3abf5b863f0..15de6269856 100644 --- a/src/coreComponents/schema/schema.xsd.other +++ b/src/coreComponents/schema/schema.xsd.other @@ -486,7 +486,7 @@ - + @@ -531,6 +531,7 @@ + @@ -572,7 +573,7 @@ - + @@ -609,7 +610,7 @@ - + @@ -660,7 +661,7 @@ - + @@ -701,7 +702,7 @@ - + @@ -734,7 +735,7 @@ - + @@ -745,7 +746,7 @@ - + @@ -758,7 +759,7 @@ - + @@ -771,7 +772,7 @@ - + @@ -787,7 +788,7 @@ - + @@ -821,7 +822,7 @@ - + @@ -884,7 +885,7 @@ - + @@ -915,7 +916,7 @@ - + @@ -928,7 +929,7 @@ - + @@ -941,10 +942,21 @@ - + + + + + + + + + + + + @@ -954,7 +966,7 @@ - + @@ -967,7 +979,7 @@ - + @@ -982,7 +994,7 @@ - + @@ -993,7 +1005,7 @@ - + @@ -1006,7 +1018,7 @@ - + @@ -1017,7 +1029,7 @@ - + @@ -1028,7 +1040,7 @@ - + @@ -1039,7 +1051,7 @@ - + @@ -1050,7 +1062,7 @@ - + @@ -1063,7 +1075,7 @@ - + @@ -1074,7 +1086,7 @@ - + @@ -1085,7 +1097,7 @@ - + @@ -1098,7 +1110,7 @@ - + @@ -1113,7 +1125,7 @@ - + @@ -1128,7 +1140,7 @@ - + @@ -1141,7 +1153,7 @@ - + @@ -1156,7 +1168,7 @@ - + @@ -1167,7 +1179,7 @@ - + @@ -1180,7 +1192,7 @@ - + @@ -1193,7 +1205,7 @@ - + @@ -1208,7 +1220,7 @@ - + @@ -1224,7 +1236,7 @@ - + @@ -1239,7 +1251,7 @@ - + @@ -1256,7 +1268,7 @@ - + @@ -1273,7 +1285,7 @@ - + @@ -1290,7 +1302,7 @@ - + @@ -1305,7 +1317,7 @@ - + @@ -1318,7 +1330,7 @@ - + @@ -1357,7 +1369,7 @@ - + @@ -1386,7 +1398,7 @@ - + @@ -1479,7 +1491,7 @@ - + @@ -1564,6 +1576,7 @@ + @@ -2931,6 +2944,18 @@ + + + + + + + + + + + + @@ -3103,7 +3128,7 @@ - + @@ -3131,7 +3156,7 @@ - + @@ -3150,11 +3175,11 @@ - + - + @@ -3164,7 +3189,7 @@ - + @@ -3174,11 +3199,11 @@ - + - + @@ -3188,7 +3213,7 @@ - + @@ -3198,7 +3223,7 @@ - + @@ -3208,7 +3233,7 @@ - + @@ -3232,7 +3257,7 @@ - + @@ -3250,7 +3275,7 @@ - + @@ -3262,7 +3287,7 @@ - + @@ -3274,7 +3299,7 @@ - + @@ -3282,11 +3307,11 @@ - + - + @@ -3309,7 +3334,7 @@ - + @@ -3335,7 +3360,7 @@ - + @@ -3356,7 +3381,7 @@ - + @@ -3386,7 +3411,7 @@ - + @@ -3400,7 +3425,7 @@ - + @@ -3427,7 +3452,7 @@ - + @@ -3466,7 +3491,7 @@ - + From 16715ceee677e3f375e96d35bc1b721c785cff83 Mon Sep 17 00:00:00 2001 From: DENEL Bertrand Date: Wed, 11 Dec 2024 20:10:59 -0600 Subject: [PATCH 075/102] Fixed doc. --- .../physicsSolvers/fluidFlow/docs/ImmiscibleMultiphaseFlow.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/docs/ImmiscibleMultiphaseFlow.rst b/src/coreComponents/physicsSolvers/fluidFlow/docs/ImmiscibleMultiphaseFlow.rst index 4eeb96c1578..8e6d35adfa2 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/docs/ImmiscibleMultiphaseFlow.rst +++ b/src/coreComponents/physicsSolvers/fluidFlow/docs/ImmiscibleMultiphaseFlow.rst @@ -44,7 +44,7 @@ where :math:`\phi(\mathbf{x})` is the porosity of the medium which is a function :math:`S_\ell(\mathbf{x},t)` is the saturation of the phase :math:`\ell` and similarly for the phase :math:`v`, and :math:`t` is the time. The source/sink terms :math:`q_{\ell}` and :math:`q_{v}` are positive for injection and negative for production. The phase -velocity, :math:`\boldsymbol{u}_\ell`` and :math:`\boldsymbol{u}_v`$`, are defined using +velocity, :math:`\boldsymbol{u}_\ell` and :math:`\boldsymbol{u}_v`, are defined using the multiphase extension of Darcy's law (conservation of momentum) as .. math:: From 9e32fe532966e8013463e7dbc3300b1266bc063f Mon Sep 17 00:00:00 2001 From: DENEL Bertrand Date: Thu, 12 Dec 2024 13:14:28 -0600 Subject: [PATCH 076/102] Added rebaseline infos. --- .integrated_tests.yaml | 2 +- BASELINE_NOTES.md | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.integrated_tests.yaml b/.integrated_tests.yaml index 31ce96119a9..bf17778ea48 100644 --- a/.integrated_tests.yaml +++ b/.integrated_tests.yaml @@ -1,6 +1,6 @@ baselines: bucket: geosx - baseline: integratedTests/baseline_integratedTests-pr3450-9221-37d940c + baseline: integratedTests/baseline_integratedTests-pr3251-9308-16715ce allow_fail: all: '' streak: '' diff --git a/BASELINE_NOTES.md b/BASELINE_NOTES.md index 3b097223255..b682d87860d 100644 --- a/BASELINE_NOTES.md +++ b/BASELINE_NOTES.md @@ -6,6 +6,10 @@ This file is designed to track changes to the integrated test baselines. Any developer who updates the baseline ID in the .integrated_tests.yaml file is expected to create an entry in this file with the pull request number, date, and their justification for rebaselining. These notes should be in reverse-chronological order, and use the following time format: (YYYY-MM-DD). +PR #3251 (2024 12 12) +===================== +Added tests for the newly introduced immiscible fluild solver + PR #3450 (2024-12-08) ===================== Added test for explicit runge kutta sprinslider. From 33950730985a1cc298ee02097b854567c3419763 Mon Sep 17 00:00:00 2001 From: DENEL Bertrand Date: Tue, 17 Dec 2024 16:33:04 -0600 Subject: [PATCH 077/102] Added back HYPRE_BoomerAMGSetAggNumLevels. --- src/coreComponents/linearAlgebra/interfaces/hypre/HypreMGR.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/coreComponents/linearAlgebra/interfaces/hypre/HypreMGR.hpp b/src/coreComponents/linearAlgebra/interfaces/hypre/HypreMGR.hpp index 8bacdf8b978..aae4b181579 100644 --- a/src/coreComponents/linearAlgebra/interfaces/hypre/HypreMGR.hpp +++ b/src/coreComponents/linearAlgebra/interfaces/hypre/HypreMGR.hpp @@ -213,6 +213,7 @@ class MGRStrategyBase #if GEOS_USE_HYPRE_DEVICE == GEOS_USE_HYPRE_CUDA || GEOS_USE_HYPRE_DEVICE == GEOS_USE_HYPRE_HIP GEOS_LAI_CHECK_ERROR( HYPRE_BoomerAMGSetAggInterpType( solver.ptr, hypre::getAMGAggressiveInterpolationType( LinearSolverParameters::AMG::AggInterpType::modifiedExtendedE ) ) ); GEOS_LAI_CHECK_ERROR( HYPRE_BoomerAMGSetCoarsenType( solver.ptr, hypre::getAMGCoarseningType( LinearSolverParameters::AMG::CoarseningType::PMIS ) ) ); + GEOS_LAI_CHECK_ERROR( HYPRE_BoomerAMGSetAggNumLevels( solver.ptr, 0 ) ); GEOS_LAI_CHECK_ERROR( HYPRE_BoomerAMGSetRelaxType( solver.ptr, getAMGRelaxationType( LinearSolverParameters::AMG::SmootherType::l1jacobi ) ) ); GEOS_LAI_CHECK_ERROR( HYPRE_BoomerAMGSetNumSweeps( solver.ptr, 2 ) ); GEOS_LAI_CHECK_ERROR( HYPRE_BoomerAMGSetMaxRowSum( solver.ptr, 1.0 ) ); From 84613c53830789ce1fd6ed3ef249755acf38f6d0 Mon Sep 17 00:00:00 2001 From: DENEL Bertrand Date: Tue, 17 Dec 2024 19:22:57 -0600 Subject: [PATCH 078/102] Removed ubuntu config file. --- host-configs/Stanford/ubuntu22.cmake | 44 ---------------------------- 1 file changed, 44 deletions(-) delete mode 100644 host-configs/Stanford/ubuntu22.cmake diff --git a/host-configs/Stanford/ubuntu22.cmake b/host-configs/Stanford/ubuntu22.cmake deleted file mode 100644 index 39bca094e3e..00000000000 --- a/host-configs/Stanford/ubuntu22.cmake +++ /dev/null @@ -1,44 +0,0 @@ -# file: your-platform.cmake - -# detect host and name the configuration file -site_name(HOST_NAME) -set(CONFIG_NAME "ubuntu22" CACHE PATH "") -message("CONFIG_NAME = ${CONFIG_NAME}") - -# set paths to C, C++, and Fortran compilers. Note that while GEOS does not contain any Fortran code, -# some of the third-party libraries do contain Fortran code. Thus a Fortran compiler must be specified. -set(CMAKE_C_COMPILER "/usr/bin/gcc" CACHE PATH "") -set(CMAKE_CXX_COMPILER "/usr/bin/g++" CACHE PATH "") -set(CMAKE_Fortran_COMPILER "/usr/bin/gfortran" CACHE PATH "") -set(ENABLE_FORTRAN OFF CACHE BOOL "" FORCE) - -# enable MPI and set paths to compilers and executable. -# Note that the MPI compilers are wrappers around standard serial compilers. -# Therefore, the MPI compilers must wrap the appropriate serial compilers specified -# in CMAKE_C_COMPILER, CMAKE_CXX_COMPILER, and CMAKE_Fortran_COMPILER. -set(ENABLE_MPI ON CACHE BOOL "") -set(MPI_C_COMPILER "/usr/bin/mpicc" CACHE PATH "") -set(MPI_CXX_COMPILER "/usr/bin/mpicxx" CACHE PATH "") -set(MPI_Fortran_COMPILER "/usr/bin/mpifort" CACHE PATH "") -set(MPIEXEC "/usr/bin/mpirun" CACHE PATH "") - -# define the path to blas and lapack -#set( BLAS_LIBRARIES /home/rpiazza/lib/lapack-3.11.0-linux-x86_64/libblas.so CACHE PATH "" FORCE ) -#set( LAPACK_LIBRARIES /home/rpiazza/lib/lapack-3.11.0-linux-x86_64/liblapack.so CACHE PATH "" FORCE ) - -# disable CUDA and OpenMP -set(ENABLE_CUDA OFF CACHE BOOL "" FORCE) -set(ENABLE_OPENMP OFF CACHE BOOL "" FORCE) - -# enable PVTPackage -set(ENABLE_PVTPackage ON CACHE BOOL "" FORCE) - -# enable tests -set(ENABLE_GTEST_DEATH_TESTS ON CACHE BOOL "" FORCE ) - -# define the path to your compiled installation directory -set(GEOS_TPL_DIR "/home/rpiazza/two-phase/thirdPartyLibs/install-ubuntu22-debug" CACHE PATH "") -#set(GEOSX_TPL_DIR "${GEOSX_TPL_DIR}" CACHE PATH "" FORCE) -# let GEOS define some third party libraries information for you -#include(${CMAKE_CURRENT_LIST_DIR}/tpls.cmake) -include(${CMAKE_CURRENT_LIST_DIR}/../tpls.cmake) From 04764f4c9cfbf8fe9415d70be72e0c9a46fc3f2b Mon Sep 17 00:00:00 2001 From: DENEL Bertrand Date: Tue, 28 Jan 2025 16:18:54 -0600 Subject: [PATCH 079/102] Merged with develop. --- .../fluidFlow/ImmiscibleMultiphaseFlow.hpp | 23 +------------------ 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp index 4d6ccbd8b21..329ecb3db32 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp @@ -23,31 +23,10 @@ #include "physicsSolvers/fluidFlow/FlowSolverBase.hpp" #include "fieldSpecification/FieldSpecificationManager.hpp" #include "physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp" - +#include "physicsSolvers/fluidFlow/CompositionalMultiphaseFVM.hpp" // For GravityDensityScheme namespace geos { -/** - * @brief Options for density treatment in gravity - */ -enum class GravityDensityScheme : integer -{ - ArithmeticAverage, ///< average phase density is computed using simple arithmetic average: - /// rho_ave = 0.5 * (rho_i + rho_j) - PhasePresence, ///< average phase density is computed using checking for phase presence: - /// rho_ave = 0.5 * (rho_i + rho_j) if phase is present in both cells i and j - /// = rho_i if phase is present in only cell i - /// = rho_j if phase is present in only cell j -}; - -/** - * @brief Strings for options for density treatment in gravity - */ -ENUM_STRINGS( GravityDensityScheme, - "ArithmeticAverage", - "PhasePresence" ); - - //START_SPHINX_INCLUDE_00 /** * @class ImmiscibleMultiphaseFlow From 770e4c9bb0ffc92b211aedf9888b697b4617bb6f Mon Sep 17 00:00:00 2001 From: DENEL Bertrand Date: Tue, 28 Jan 2025 17:00:51 -0600 Subject: [PATCH 080/102] Moved TwoPhaseFluid unit test. --- src/coreComponents/constitutive/unitTests/CMakeLists.txt | 3 ++- .../unitTests}/testTwoPhaseFluid.cpp | 0 src/coreComponents/unitTests/constitutiveTests/CMakeLists.txt | 3 +-- 3 files changed, 3 insertions(+), 3 deletions(-) rename src/coreComponents/{unitTests/constitutiveTests => constitutive/unitTests}/testTwoPhaseFluid.cpp (100%) diff --git a/src/coreComponents/constitutive/unitTests/CMakeLists.txt b/src/coreComponents/constitutive/unitTests/CMakeLists.txt index aa095d493c8..d7cdc296795 100644 --- a/src/coreComponents/constitutive/unitTests/CMakeLists.txt +++ b/src/coreComponents/constitutive/unitTests/CMakeLists.txt @@ -18,7 +18,8 @@ set( gtest_geosx_tests testPropertyConversions.cpp testStabilityTest2Comp.cpp testStabilityTest9Comp.cpp - testRachfordRice.cpp ) + testRachfordRice.cpp + testTwoPhaseFluid.cpp ) set( dependencyList gtest blas lapack constitutive ${parallelDeps} ) diff --git a/src/coreComponents/unitTests/constitutiveTests/testTwoPhaseFluid.cpp b/src/coreComponents/constitutive/unitTests/testTwoPhaseFluid.cpp similarity index 100% rename from src/coreComponents/unitTests/constitutiveTests/testTwoPhaseFluid.cpp rename to src/coreComponents/constitutive/unitTests/testTwoPhaseFluid.cpp diff --git a/src/coreComponents/unitTests/constitutiveTests/CMakeLists.txt b/src/coreComponents/unitTests/constitutiveTests/CMakeLists.txt index 6f9608fadf6..0d13b0ef63a 100644 --- a/src/coreComponents/unitTests/constitutiveTests/CMakeLists.txt +++ b/src/coreComponents/unitTests/constitutiveTests/CMakeLists.txt @@ -9,8 +9,7 @@ set( gtest_geosx_tests testMultiFluidDeadOil.cpp testMultiFluidLiveOil.cpp testRelPerm.cpp - testRelPermHysteresis.cpp - testTwoPhaseFluid.cpp ) + testRelPermHysteresis.cpp ) set( gtest_triaxial_xmls testTriaxial_druckerPragerExtended.xml From 254d4df4a0fca165405e35aed8a6f3478bff3082 Mon Sep 17 00:00:00 2001 From: DENEL Bertrand Date: Tue, 28 Jan 2025 17:11:59 -0600 Subject: [PATCH 081/102] Removed HYPRE_BoomerAMGSetAggNumLevels. Hypre setup to be addressed in a seperate PR. --- src/coreComponents/linearAlgebra/interfaces/hypre/HypreMGR.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/coreComponents/linearAlgebra/interfaces/hypre/HypreMGR.hpp b/src/coreComponents/linearAlgebra/interfaces/hypre/HypreMGR.hpp index d9b76cf096d..c45bc4fe873 100644 --- a/src/coreComponents/linearAlgebra/interfaces/hypre/HypreMGR.hpp +++ b/src/coreComponents/linearAlgebra/interfaces/hypre/HypreMGR.hpp @@ -213,7 +213,6 @@ class MGRStrategyBase #if GEOS_USE_HYPRE_DEVICE == GEOS_USE_HYPRE_CUDA || GEOS_USE_HYPRE_DEVICE == GEOS_USE_HYPRE_HIP GEOS_LAI_CHECK_ERROR( HYPRE_BoomerAMGSetAggInterpType( solver.ptr, hypre::getAMGAggressiveInterpolationType( LinearSolverParameters::AMG::AggInterpType::modifiedExtendedE ) ) ); GEOS_LAI_CHECK_ERROR( HYPRE_BoomerAMGSetCoarsenType( solver.ptr, hypre::getAMGCoarseningType( LinearSolverParameters::AMG::CoarseningType::PMIS ) ) ); - GEOS_LAI_CHECK_ERROR( HYPRE_BoomerAMGSetAggNumLevels( solver.ptr, 0 ) ); GEOS_LAI_CHECK_ERROR( HYPRE_BoomerAMGSetRelaxType( solver.ptr, getAMGRelaxationType( LinearSolverParameters::AMG::SmootherType::l1jacobi ) ) ); GEOS_LAI_CHECK_ERROR( HYPRE_BoomerAMGSetNumSweeps( solver.ptr, 2 ) ); GEOS_LAI_CHECK_ERROR( HYPRE_BoomerAMGSetMaxRowSum( solver.ptr, 1.0 ) ); From bb6b0afbcfbceb4d5c2a7c4d642011e3e33bf5cb Mon Sep 17 00:00:00 2001 From: DENEL Bertrand Date: Tue, 28 Jan 2025 17:53:08 -0600 Subject: [PATCH 082/102] Removed commented sections. --- .../fluid/twophasefluid/TwoPhaseFluid.cpp | 7 ----- .../fluidFlow/ImmiscibleMultiphaseFlow.cpp | 29 ++----------------- 2 files changed, 2 insertions(+), 34 deletions(-) diff --git a/src/coreComponents/constitutive/fluid/twophasefluid/TwoPhaseFluid.cpp b/src/coreComponents/constitutive/fluid/twophasefluid/TwoPhaseFluid.cpp index 3b119e393d8..ad6379ea129 100644 --- a/src/coreComponents/constitutive/fluid/twophasefluid/TwoPhaseFluid.cpp +++ b/src/coreComponents/constitutive/fluid/twophasefluid/TwoPhaseFluid.cpp @@ -105,13 +105,6 @@ void TwoPhaseFluid::postInputInitialization() m_tableFiles.empty() ? readInputDataFromTableFunctions() : readInputDataFromFileTableFunctions(); checkTableConsistency(); - /* TODO - // call to correctly set member array tertiary sizes on the 'main' material object - resizeFields( 0, 0 ); - - // set labels on array wrappers for plottable fields - setLabels(); - */ } diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp index 8a43a9218ce..87969dc05aa 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp @@ -100,9 +100,6 @@ void ImmiscibleMultiphaseFlow::registerDataOnMesh( Group & meshBodies ) { FlowSolverBase::registerDataOnMesh( meshBodies ); - // DomainPartition const & domain = this->getGroupByPath< DomainPartition >( "/Problem/domain" ); - // ConstitutiveManager const & cm = domain.getConstitutiveManager(); - // 0. Find a "reference" fluid model name (at this point, models are already attached to subregions) forDiscretizationOnMeshTargets( meshBodies, [&]( string const &, MeshLevel & mesh, @@ -174,10 +171,6 @@ void ImmiscibleMultiphaseFlow::registerDataOnMesh( Group & meshBodies ) } ); - // FaceManager & faceManager = mesh.getFaceManager(); - // { - // faceManager.registerField< totalMassFlux >( getName() ); - // } } ); } @@ -213,16 +206,10 @@ void ImmiscibleMultiphaseFlow::initializePreSubGroups() FlowSolverBase::initializePreSubGroups(); DomainPartition & domain = this->getGroupByPath< DomainPartition >( "/Problem/domain" ); - // ConstitutiveManager const & cm = domain.getConstitutiveManager(); - - // // 1. Validate various models against each other (must have same phases and components) - // validateConstitutiveModels( domain ); - // 2. Set the value of temperature forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, MeshLevel & mesh, arrayView1d< string const > const & regionNames ) - { mesh.getElemManager().forElementSubRegions( regionNames, [&]( localIndex const, @@ -253,7 +240,6 @@ void ImmiscibleMultiphaseFlow::updateFluidModel( ObjectManagerBase & dataGroup ) } - void ImmiscibleMultiphaseFlow::updateRelPermModel( ObjectManagerBase & dataGroup ) const { GEOS_MARK_FUNCTION; @@ -683,18 +669,11 @@ void ImmiscibleMultiphaseFlow::applyBoundaryConditions( real64 const time_n, // apply pressure boundary conditions. applyDirichletBC( time_n, dt, dofManager, domain, localMatrix.toViewConstSizes(), localRhs.toView() ); -// apply flux boundary conditions + // apply flux boundary conditions applySourceFluxBC( time_n, dt, dofManager, domain, localMatrix.toViewConstSizes(), localRhs.toView() ); - - // for( localIndex row = 0; row < localMatrix.toViewConstSizes().numRows(); ++row ) - // { - // std::cout << "row " << row << std::endl; - // std::cout << "\tcolumns: " << localMatrix.toViewConstSizes().getColumns( row ) << std::endl; - // std::cout << "\tvalues: " << localMatrix.toViewConstSizes().getEntries( row ) << std::endl; - // } - } + namespace { char const bcLogMessage[] = @@ -1065,10 +1044,8 @@ void ImmiscibleMultiphaseFlow::applySystemSolution( DofManager const & dofManage GEOS_UNUSED_VAR( dt ); DofManager::CompMask pressureMask( m_numDofPerCell, 0, 1 ); - //DofManager::CompMask PhaseMask( m_numDofPerCell, 1, m_numPhases ); // 1. apply the pressure update - dofManager.addVectorToField( localSolution, viewKeyStruct::elemDofFieldString(), fields::flow::pressure::key(), @@ -1076,7 +1053,6 @@ void ImmiscibleMultiphaseFlow::applySystemSolution( DofManager const & dofManage pressureMask ); // 2. apply the phaseVolumeFraction update - dofManager.addVectorToField( localSolution, viewKeyStruct::elemDofFieldString(), fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key(), @@ -1095,7 +1071,6 @@ void ImmiscibleMultiphaseFlow::applySystemSolution( DofManager const & dofManage CommunicationTools::getInstance().synchronizeFields( fieldsToBeSync, mesh, domain.getNeighbors(), true ); } ); - } From 23c52401b6bb88fe19f132eb2e94b670dfb76ed3 Mon Sep 17 00:00:00 2001 From: Ammara-14 Date: Fri, 31 Jan 2025 16:09:51 -0800 Subject: [PATCH 083/102] Additing validateDirichletBC and SourceFluxStats wrapper --- .../fluidFlow/ImmiscibleMultiphaseFlow.cpp | 148 ++++++++++++++++-- .../fluidFlow/ImmiscibleMultiphaseFlow.hpp | 8 + 2 files changed, 139 insertions(+), 17 deletions(-) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp index 87969dc05aa..13962c2d973 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp @@ -30,7 +30,9 @@ #include "constitutive/capillaryPressure/capillaryPressureSelector.hpp" #include "constitutive/relativePermeability/RelativePermeabilitySelector.hpp" +#include "fieldSpecification/EquilibriumInitialCondition.hpp" #include "fieldSpecification/SourceFluxBoundaryCondition.hpp" +#include "physicsSolvers/fluidFlow/SourceFluxStatistics.hpp" #include "constitutive/ConstitutivePassThru.hpp" #include "constitutive/fluid/twophasefluid/TwoPhaseFluid.hpp" @@ -677,13 +679,126 @@ void ImmiscibleMultiphaseFlow::applyBoundaryConditions( real64 const time_n, namespace { char const bcLogMessage[] = - "CompositionalMultiphaseBase {}: at time {}s, " + "ImmiscibleMultiphaseFlow {}: at time {}s, " "the <{}> boundary condition '{}' is applied to the element set '{}' in subRegion '{}'. " "\nThe scale of this boundary condition is {} and multiplies the value of the provided function (if any). " "\nThe total number of target elements (including ghost elements) is {}. " "\nNote that if this number is equal to zero for all subRegions, the boundary condition will not be applied on this element set."; } +bool ImmiscibleMultiphaseFlow::validateDirichletBC( DomainPartition & domain, + real64 const time ) const +{ + constexpr integer MAX_NP = 2; + FieldSpecificationManager & fsManager = FieldSpecificationManager::getInstance(); + + bool bcConsistent = true; + + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, + MeshLevel & mesh, + arrayView1d< string const > const & ) + { + // map: regionName -> subRegionName -> setName -> numPhases to check pressure/phase are present consistent + map< string, map< string, map< string, ComponentMask< MAX_NP > > > > bcPresCompStatusMap; + + // 1. Check pressure Dirichlet BCs + fsManager.apply< ElementSubRegionBase >( time, + mesh, + fields::flow::pressure::key(), + [&]( FieldSpecificationBase const &, + string const & setName, + SortedArrayView< localIndex const > const &, + ElementSubRegionBase & subRegion, + string const & ) + { + // Check whether pressure has already been applied to this set + string const & subRegionName = subRegion.getName(); + string const & regionName = subRegion.getParent().getParent().getName(); + + auto & subRegionSetMap = bcPresCompStatusMap[regionName][subRegionName]; + if( subRegionSetMap.count( setName ) > 0 ) + { + bcConsistent = false; + GEOS_WARNING( BCMessage::pressureConflict( regionName, subRegionName, setName, + fields::flow::pressure::key() ) ); + } + subRegionSetMap[setName].setNumComp( m_numPhases ); + } ); + // 2. Check saturation Dirichlet BCs + fsManager.apply< ElementSubRegionBase >( time, + mesh, + fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key(), + [&] ( FieldSpecificationBase const & fs, + string const & setName, + SortedArrayView< localIndex const > const &, + ElementSubRegionBase & subRegion, + string const & ) + { + string const & subRegionName = subRegion.getName( ); + string const & regionName = subRegion.getParent().getParent().getName(); + integer const comp = fs.getComponent(); + + auto & subRegionSetMap = bcPresCompStatusMap[regionName][subRegionName]; + if( subRegionSetMap.count( setName ) == 0 ) + { + bcConsistent = false; + GEOS_WARNING( BCMessage::missingPressure( regionName, subRegionName, setName, + fields::flow::pressure::key() ) ); + } + if( comp < 0 || comp >= m_numPhases ) + { + bcConsistent = false; + GEOS_WARNING( BCMessage::invalidComponentIndex( comp, fs.getName(), + fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key() ) ); + return; // can't check next part with invalid component id + } + + ComponentMask< MAX_NP > & compMask = subRegionSetMap[setName]; + if( compMask[comp] ) + { + bcConsistent = false; + fsManager.forSubGroups< EquilibriumInitialCondition >( [&] ( EquilibriumInitialCondition const & bc ) + { + arrayView1d< string const > componentNames = bc.getComponentNames(); + GEOS_WARNING( BCMessage::conflictingComposition( comp, componentNames[comp], + regionName, subRegionName, setName, + fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key() ) ); + } ); + } + compMask.set( comp ); + } ); + + // 3.2 Check consistency between composition BC applied to sets + // Note: for a temperature-only boundary condition, this loop does not do anything + for( auto const & regionEntry : bcPresCompStatusMap ) + { + for( auto const & subRegionEntry : regionEntry.second ) + { + for( auto const & setEntry : subRegionEntry.second ) + { + ComponentMask< MAX_NP > const & compMask = setEntry.second; + + fsManager.forSubGroups< EquilibriumInitialCondition >( [&] ( EquilibriumInitialCondition const & fs ) + { + arrayView1d< string const > componentNames = fs.getComponentNames(); + for( int ic = 0; ic < componentNames.size(); ic++ ) + { + if( !compMask[ic] ) + { + bcConsistent = false; + GEOS_WARNING( BCMessage::notAppliedOnRegion( ic, componentNames[ic], + regionEntry.first, subRegionEntry.first, setEntry.first, + fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key() ) ); + } + } + } ); + } + } + } + } ); + + return bcConsistent; +} void ImmiscibleMultiphaseFlow::applyDirichletBC( real64 const time_n, real64 const dt, @@ -694,12 +809,12 @@ void ImmiscibleMultiphaseFlow::applyDirichletBC( real64 const time_n, { GEOS_MARK_FUNCTION; - // // Only validate BC at the beginning of Newton loop - // if( m_nonlinearSolverParameters.m_numNewtonIterations == 0 ) - // { - // bool const bcConsistent = validateDirichletBC( domain, time_n + dt ); - // GEOS_ERROR_IF( !bcConsistent, GEOS_FMT( "CompositionalMultiphaseBase {}: inconsistent boundary conditions", getDataContext() ) ); - // } + // Only validate BC at the beginning of Newton loop + if( m_nonlinearSolverParameters.m_numNewtonIterations == 0 ) + { + bool const bcConsistent = validateDirichletBC( domain, time_n + dt ); + GEOS_ERROR_IF( !bcConsistent, GEOS_FMT( "ImmiscibleMultiphaseFlow {}: inconsistent boundary conditions", getDataContext() ) ); + } FieldSpecificationManager & fsManager = FieldSpecificationManager::getInstance(); @@ -719,7 +834,7 @@ void ImmiscibleMultiphaseFlow::applyDirichletBC( real64 const time_n, globalIndex const rankOffset = dofManager.rankOffset(); string const dofKey = dofManager.getKey( viewKeyStruct::elemDofFieldString() ); - // 3. Call constitutive update, back-calculate target global component densities and apply to the system + // 3. Call constitutive update fsManager.apply< ElementSubRegionBase >( time_n + dt, mesh, fields::flow::pressure::key(), @@ -939,19 +1054,18 @@ void ImmiscibleMultiphaseFlow::applySourceFluxBC( real64 const time, } } ); - // SourceFluxStatsAggregator::forAllFluxStatWrappers( subRegion, fs.getName(), - // [&]( SourceFluxStatsAggregator::WrappedStats & wrapper ) - // { - // // set the new sub-region statistics for this timestep - // array1d< real64 > massProdArr{ m_numPhases }; - // massProdArr[fluidPhaseId] = massProd.get(); - // wrapper.gatherTimeStepStats( time, dt, massProdArr.toViewConst(), targetSet.size() ); - // } ); + SourceFluxStatsAggregator::forAllFluxStatWrappers( subRegion, fs.getName(), + [&]( SourceFluxStatsAggregator::WrappedStats & wrapper ) + { + // set the new sub-region statistics for this timestep + array1d< real64 > massProdArr{ m_numPhases }; + massProdArr[fluidPhaseId] = massProd.get(); + wrapper.gatherTimeStepStats( time, dt, massProdArr.toViewConst(), targetSet.size() ); + } ); } ); } ); } - real64 ImmiscibleMultiphaseFlow::calculateResidualNorm( real64 const & GEOS_UNUSED_PARAM( time_n ), real64 const & GEOS_UNUSED_PARAM( dt ), DomainPartition const & domain, diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp index 329ecb3db32..8d5230aa557 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp @@ -305,6 +305,14 @@ class ImmiscibleMultiphaseFlow : public FlowSolverBase private: + /** + * @brief Utility function to validate the consistency of Dirichlet BC input + * @param[in] domain the domain partition + * @param[in] time the time at the end of the time step (time_n + dt) + */ + bool validateDirichletBC( DomainPartition & domain, + real64 const time ) const; + virtual void setConstitutiveNames( ElementSubRegionBase & subRegion ) const override; }; From 510ed8c4340a280d557493996fe2375278039d31 Mon Sep 17 00:00:00 2001 From: Pavel Tomin Date: Wed, 26 Feb 2025 09:54:17 -0600 Subject: [PATCH 084/102] code style --- .../physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp index 13962c2d973..c8ff3335f22 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp @@ -687,7 +687,7 @@ char const bcLogMessage[] = } bool ImmiscibleMultiphaseFlow::validateDirichletBC( DomainPartition & domain, - real64 const time ) const + real64 const time ) const { constexpr integer MAX_NP = 2; FieldSpecificationManager & fsManager = FieldSpecificationManager::getInstance(); @@ -723,9 +723,9 @@ bool ImmiscibleMultiphaseFlow::validateDirichletBC( DomainPartition & domain, fields::flow::pressure::key() ) ); } subRegionSetMap[setName].setNumComp( m_numPhases ); - } ); + } ); // 2. Check saturation Dirichlet BCs - fsManager.apply< ElementSubRegionBase >( time, + fsManager.apply< ElementSubRegionBase >( time, mesh, fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key(), [&] ( FieldSpecificationBase const & fs, @@ -795,7 +795,7 @@ bool ImmiscibleMultiphaseFlow::validateDirichletBC( DomainPartition & domain, } } } - } ); + } ); return bcConsistent; } From 66a166598ba085fcbf583e757bbaad17249faed0 Mon Sep 17 00:00:00 2001 From: Pavel Tomin Date: Wed, 26 Feb 2025 11:39:08 -0600 Subject: [PATCH 085/102] build fix --- .../fluid/twophasefluid/TwoPhaseFluid.hpp | 4 +- .../fluidFlow/ImmiscibleMultiphaseFlow.cpp | 40 +++++++++---------- .../fluidFlow/ImmiscibleMultiphaseFlow.hpp | 2 +- .../testImmiscibleMultiphaseFlow.cpp | 2 +- 4 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/coreComponents/constitutive/fluid/twophasefluid/TwoPhaseFluid.hpp b/src/coreComponents/constitutive/fluid/twophasefluid/TwoPhaseFluid.hpp index d1da2681a25..6c236a433a0 100644 --- a/src/coreComponents/constitutive/fluid/twophasefluid/TwoPhaseFluid.hpp +++ b/src/coreComponents/constitutive/fluid/twophasefluid/TwoPhaseFluid.hpp @@ -74,7 +74,7 @@ class TwoPhaseFluid : public ConstitutiveBase * @brief Getter for the fluid phase names * @return an array storing the phase names */ - arrayView1d< string const > phaseNames() const { return m_phaseNames; } + string_array const & phaseNames() const { return m_phaseNames; } struct viewKeyStruct : ConstitutiveBase::viewKeyStruct { @@ -197,7 +197,7 @@ class TwoPhaseFluid : public ConstitutiveBase }; //class KernelWrapper - array1d< string > m_phaseNames; + string_array m_phaseNames; path_array m_tableFiles; diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp index c8ff3335f22..a8019424283 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp @@ -105,7 +105,7 @@ void ImmiscibleMultiphaseFlow::registerDataOnMesh( Group & meshBodies ) // 0. Find a "reference" fluid model name (at this point, models are already attached to subregions) forDiscretizationOnMeshTargets( meshBodies, [&]( string const &, MeshLevel & mesh, - arrayView1d< string const > const & regionNames ) + string_array const & regionNames ) { mesh.getElemManager().forElementSubRegions( regionNames, [&]( localIndex const, @@ -125,7 +125,7 @@ void ImmiscibleMultiphaseFlow::registerDataOnMesh( Group & meshBodies ) // 2. Register and resize all fields as necessary forDiscretizationOnMeshTargets( meshBodies, [&]( string const &, MeshLevel & mesh, - arrayView1d< string const > const & regionNames ) + string_array const & regionNames ) { mesh.getElemManager().forElementSubRegions( regionNames, [&]( localIndex const, @@ -211,7 +211,7 @@ void ImmiscibleMultiphaseFlow::initializePreSubGroups() forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, MeshLevel & mesh, - arrayView1d< string const > const & regionNames ) + string_array const & regionNames ) { mesh.getElemManager().forElementSubRegions( regionNames, [&]( localIndex const, @@ -357,7 +357,7 @@ void ImmiscibleMultiphaseFlow::updatePhaseMobility( ObjectManagerBase & dataGrou } void ImmiscibleMultiphaseFlow::initializeFluidState( MeshLevel & mesh, - arrayView1d< string const > const & regionNames ) + string_array const & regionNames ) { GEOS_MARK_FUNCTION; @@ -481,7 +481,7 @@ void ImmiscibleMultiphaseFlow::initializePostInitialConditionsPreSubGroups() forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, MeshLevel & mesh, - arrayView1d< string const > const & regionNames ) + string_array const & regionNames ) { FieldIdentifiers fieldsToBeSync; fieldsToBeSync.addElementFields( { fields::flow::pressure::key(), @@ -502,7 +502,7 @@ ImmiscibleMultiphaseFlow::implicitStepSetup( real64 const & GEOS_UNUSED_PARAM( t { forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, MeshLevel & mesh, - arrayView1d< string const > const & regionNames ) + string_array const & regionNames ) { mesh.getElemManager().forElementSubRegions< CellElementSubRegion, SurfaceElementSubRegion >( regionNames, @@ -570,7 +570,7 @@ void ImmiscibleMultiphaseFlow::assembleAccumulationTerm( DomainPartition & domai forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, MeshLevel const & mesh, - arrayView1d< string const > const & regionNames ) + string_array const & regionNames ) { mesh.getElemManager().forElementSubRegions( regionNames, [&]( localIndex const, @@ -615,7 +615,7 @@ void ImmiscibleMultiphaseFlow::assembleFluxTerms( real64 const dt, forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&] ( string const &, MeshLevel const & mesh, - arrayView1d< string const > const & ) + string_array const & ) { fluxApprox.forAllStencils( mesh, [&]( auto & stencil ) { @@ -696,7 +696,7 @@ bool ImmiscibleMultiphaseFlow::validateDirichletBC( DomainPartition & domain, forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, MeshLevel & mesh, - arrayView1d< string const > const & ) + string_array const & ) { // map: regionName -> subRegionName -> setName -> numPhases to check pressure/phase are present consistent map< string, map< string, map< string, ComponentMask< MAX_NP > > > > bcPresCompStatusMap; @@ -759,7 +759,7 @@ bool ImmiscibleMultiphaseFlow::validateDirichletBC( DomainPartition & domain, bcConsistent = false; fsManager.forSubGroups< EquilibriumInitialCondition >( [&] ( EquilibriumInitialCondition const & bc ) { - arrayView1d< string const > componentNames = bc.getComponentNames(); + string_array const & componentNames = bc.getComponentNames(); GEOS_WARNING( BCMessage::conflictingComposition( comp, componentNames[comp], regionName, subRegionName, setName, fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key() ) ); @@ -780,8 +780,8 @@ bool ImmiscibleMultiphaseFlow::validateDirichletBC( DomainPartition & domain, fsManager.forSubGroups< EquilibriumInitialCondition >( [&] ( EquilibriumInitialCondition const & fs ) { - arrayView1d< string const > componentNames = fs.getComponentNames(); - for( int ic = 0; ic < componentNames.size(); ic++ ) + string_array const & componentNames = fs.getComponentNames(); + for( size_t ic = 0; ic < componentNames.size(); ic++ ) { if( !compMask[ic] ) { @@ -820,7 +820,7 @@ void ImmiscibleMultiphaseFlow::applyDirichletBC( real64 const time_n, forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, MeshLevel & mesh, - arrayView1d< string const > const & ) + string_array const & ) { // 1. Apply pressure Dirichlet BCs, store in a separate field @@ -945,7 +945,7 @@ void ImmiscibleMultiphaseFlow::applySourceFluxBC( real64 const time, forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, MeshLevel & mesh, - arrayView1d< string const > const & ) + string_array const & ) { fsManager.apply< ElementSubRegionBase, @@ -1085,7 +1085,7 @@ real64 ImmiscibleMultiphaseFlow::calculateResidualNorm( real64 const & GEOS_UNUS forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, MeshLevel const & mesh, - arrayView1d< string const > const & regionNames ) + string_array const & regionNames ) { mesh.getElemManager().forElementSubRegions( regionNames, [&]( localIndex const, @@ -1176,7 +1176,7 @@ void ImmiscibleMultiphaseFlow::applySystemSolution( DofManager const & dofManage // 3. synchronize forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&] ( string const &, MeshLevel & mesh, - arrayView1d< string const > const & regionNames ) + string_array const & regionNames ) { std::vector< string > fields{ fields::flow::pressure::key(), fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key() }; @@ -1207,7 +1207,7 @@ void ImmiscibleMultiphaseFlow::resetStateToBeginningOfStep( DomainPartition & do forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, MeshLevel & mesh, - arrayView1d< string const > const & regionNames ) + string_array const & regionNames ) { mesh.getElemManager().forElementSubRegions< CellElementSubRegion, SurfaceElementSubRegion >( regionNames, @@ -1263,7 +1263,7 @@ void ImmiscibleMultiphaseFlow::implicitStepComplete( real64 const & time, forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, MeshLevel & mesh, - arrayView1d< string const > const & regionNames ) + string_array const & regionNames ) { mesh.getElemManager().forElementSubRegions( regionNames, [&]( localIndex const, @@ -1333,7 +1333,7 @@ void ImmiscibleMultiphaseFlow::updateState( DomainPartition & domain ) forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, MeshLevel & mesh, - arrayView1d< string const > const & regionNames ) + string_array const & regionNames ) { mesh.getElemManager().forElementSubRegions< CellElementSubRegion, SurfaceElementSubRegion >( regionNames, [&]( localIndex const, @@ -1364,7 +1364,7 @@ real64 ImmiscibleMultiphaseFlow::setNextDtBasedOnStateChange( real64 const & cur forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, MeshLevel & mesh, - arrayView1d< string const > const & regionNames ) + string_array const & regionNames ) { mesh.getElemManager().forElementSubRegions( regionNames, [&]( localIndex const, diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp index 8d5230aa557..5d876f9cfd7 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp @@ -206,7 +206,7 @@ class ImmiscibleMultiphaseFlow : public FlowSolverBase virtual void initializePostInitialConditionsPreSubGroups() override; - virtual void initializeFluidState( MeshLevel & mesh, arrayView1d< string const > const & regionNames ) override; + virtual void initializeFluidState( MeshLevel & mesh, string_array const & regionNames ) override; /** diff --git a/src/coreComponents/unitTests/fluidFlowTests/testImmiscibleMultiphaseFlow.cpp b/src/coreComponents/unitTests/fluidFlowTests/testImmiscibleMultiphaseFlow.cpp index d86be36ea17..175b5197e13 100644 --- a/src/coreComponents/unitTests/fluidFlowTests/testImmiscibleMultiphaseFlow.cpp +++ b/src/coreComponents/unitTests/fluidFlowTests/testImmiscibleMultiphaseFlow.cpp @@ -256,7 +256,7 @@ void fillCellCenteredNumericalJacobian( ImmiscibleMultiphaseFlow & solver, solver.forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, MeshLevel & mesh, - arrayView1d< string const > const & regionNames ) + string_array const & regionNames ) { mesh.getElemManager().forElementSubRegions( regionNames, [&]( localIndex const, From ab3cd3b32cfd1657452708bc1b364b768a2c9a97 Mon Sep 17 00:00:00 2001 From: Pavel Tomin Date: Wed, 26 Feb 2025 11:49:54 -0600 Subject: [PATCH 086/102] test build fix --- .../constitutive/unitTests/testTwoPhaseFluid.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/coreComponents/constitutive/unitTests/testTwoPhaseFluid.cpp b/src/coreComponents/constitutive/unitTests/testTwoPhaseFluid.cpp index b456b3468bb..39cc87395a6 100644 --- a/src/coreComponents/constitutive/unitTests/testTwoPhaseFluid.cpp +++ b/src/coreComponents/constitutive/unitTests/testTwoPhaseFluid.cpp @@ -207,13 +207,16 @@ TwoPhaseFluid * TwoPhaseFluidTest< true >::makeTwoPhaseFluid( string const & nam TwoPhaseFluid & fluid = parent.registerGroup< TwoPhaseFluid >( name ); string_array & phaseNames = fluid.getReference< string_array >( TwoPhaseFluid::viewKeyStruct::phaseNamesString() ); - fill< 2 >( phaseNames, {"oil", "water"} ); + phaseNames[0] = "oil"; + phaseNames[1] = "water"; string_array & densityTableNames = fluid.getReference< string_array >( TwoPhaseFluid::viewKeyStruct::densityTableNamesString() ); - fill< 2 >( densityTableNames, {"densityTablePhase0", "densityTablePhase1"} ); + densityTableNames[0] = "densityTablePhase0"; + densityTableNames[1] = "densityTablePhase1"; string_array & viscosityTableNames = fluid.getReference< string_array >( TwoPhaseFluid::viewKeyStruct::viscosityTableNamesString() ); - fill< 2 >( viscosityTableNames, {"viscosityTablePhase0", "viscosityTablePhase1"} ); + viscosityTableNames[0] = "viscosityTablePhase0"; + viscosityTableNames[1] = "viscosityTablePhase1"; fluid.postInputInitializationRecursive(); return &fluid; From 79b9ff568ac75f8fd4967fa2d5081f7733d98241 Mon Sep 17 00:00:00 2001 From: Pavel Tomin Date: Wed, 26 Feb 2025 13:29:42 -0600 Subject: [PATCH 087/102] test fix again --- .../fluid/twophasefluid/TwoPhaseFluid.hpp | 4 ++-- .../constitutive/unitTests/testTwoPhaseFluid.cpp | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/coreComponents/constitutive/fluid/twophasefluid/TwoPhaseFluid.hpp b/src/coreComponents/constitutive/fluid/twophasefluid/TwoPhaseFluid.hpp index 6c236a433a0..18cdc357bb0 100644 --- a/src/coreComponents/constitutive/fluid/twophasefluid/TwoPhaseFluid.hpp +++ b/src/coreComponents/constitutive/fluid/twophasefluid/TwoPhaseFluid.hpp @@ -203,10 +203,10 @@ class TwoPhaseFluid : public ConstitutiveBase path_array m_tableFiles; /// Names of the density tables (one per phase) - array1d< string > m_densityTableNames; + string_array m_densityTableNames; /// Names of the viscosity tables (one per phase) - array1d< string > m_viscosityTableNames; + string_array m_viscosityTableNames; PhaseProp m_phaseDensity; PhaseProp m_phaseViscosity; diff --git a/src/coreComponents/constitutive/unitTests/testTwoPhaseFluid.cpp b/src/coreComponents/constitutive/unitTests/testTwoPhaseFluid.cpp index 39cc87395a6..207668e29cb 100644 --- a/src/coreComponents/constitutive/unitTests/testTwoPhaseFluid.cpp +++ b/src/coreComponents/constitutive/unitTests/testTwoPhaseFluid.cpp @@ -207,16 +207,16 @@ TwoPhaseFluid * TwoPhaseFluidTest< true >::makeTwoPhaseFluid( string const & nam TwoPhaseFluid & fluid = parent.registerGroup< TwoPhaseFluid >( name ); string_array & phaseNames = fluid.getReference< string_array >( TwoPhaseFluid::viewKeyStruct::phaseNamesString() ); - phaseNames[0] = "oil"; - phaseNames[1] = "water"; + phaseNames.emplace_back( "oil" ); + phaseNames.emplace_back( "water" ); string_array & densityTableNames = fluid.getReference< string_array >( TwoPhaseFluid::viewKeyStruct::densityTableNamesString() ); - densityTableNames[0] = "densityTablePhase0"; - densityTableNames[1] = "densityTablePhase1"; + densityTableNames.emplace_back( "densityTablePhase0" ); + densityTableNames.emplace_back( "densityTablePhase1" ); string_array & viscosityTableNames = fluid.getReference< string_array >( TwoPhaseFluid::viewKeyStruct::viscosityTableNamesString() ); - viscosityTableNames[0] = "viscosityTablePhase0"; - viscosityTableNames[1] = "viscosityTablePhase1"; + viscosityTableNames.emplace_back( "viscosityTablePhase0" ); + viscosityTableNames.emplace_back( "viscosityTablePhase1" ); fluid.postInputInitializationRecursive(); return &fluid; From cfbddf83d1d7778b0778fae498dadf5376b59deb Mon Sep 17 00:00:00 2001 From: Ammara-14 Date: Thu, 27 Feb 2025 12:46:15 -0800 Subject: [PATCH 088/102] Initial implementation - trying to pass the capillary pressure model to the compute flux --- .../fluidFlow/ImmiscibleMultiphaseFlow.cpp | 22 ++++- .../ImmiscibleMultiphaseKernels.hpp | 89 ++++++++++++++++++- 2 files changed, 108 insertions(+), 3 deletions(-) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp index 13962c2d973..08472eb47e6 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp @@ -613,18 +613,37 @@ void ImmiscibleMultiphaseFlow::assembleFluxTerms( real64 const dt, string const & dofKey = dofManager.getKey( viewKeyStruct::elemDofFieldString() ); + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&] ( string const &, MeshLevel const & mesh, - arrayView1d< string const > const & ) + arrayView1d< string const > const & regionNames ) { + + + fluxApprox.forAllStencils( mesh, [&]( auto & stencil ) { + mesh.getElemManager().forElementSubRegions( regionNames, + [&]( localIndex const, + ElementSubRegionBase const & subRegion ) + { + // if( m_hasCapPressure ) + // { + string const & cappresName = subRegion.getReference< string >( viewKeyStruct::capPressureNamesString() ); + CapillaryPressureBase const & capPressure = getConstitutiveModel< CapillaryPressureBase >( subRegion, cappresName ); + // constitutive::constitutiveUpdatePassThru( capPressure, [&] ( auto & castedCapPres ) + // { + // typename TYPEOFREF( castedCapPres ) ::KernelWrapper capPresWrapper = castedCapPres.createKernelWrapper(); + // } ); + // } + typename TYPEOFREF( stencil ) ::KernelWrapper stencilWrapper = stencil.createKernelWrapper(); immiscibleMultiphaseKernels:: FaceBasedAssemblyKernelFactory::createAndLaunch< parallelDevicePolicy<> >( m_numPhases, dofManager.rankOffset(), dofKey, m_hasCapPressure, + capPressure, m_useTotalMassEquation, m_gravityDensityScheme == GravityDensityScheme::PhasePresence, getName(), @@ -633,6 +652,7 @@ void ImmiscibleMultiphaseFlow::assembleFluxTerms( real64 const dt, dt, localMatrix.toViewConstSizes(), localRhs.toView() ); + } ); } ); } ); } diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp index 0f2e4045be4..160f806d48d 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp @@ -17,8 +17,10 @@ * @file ImmiscibleMultiphaseKernels.hpp */ + #ifndef GEOS_PHYSICSSOLVERS_FLUIDFLOW_MULTIPHASEKERNELS_HPP #define GEOS_PHYSICSSOLVERS_FLUIDFLOW_MULTIPHASEKERNELS_HPP +#define Pe_max 5000000.0 #include "codingUtilities/Utilities.hpp" #include "common/DataLayouts.hpp" @@ -26,6 +28,7 @@ #include "common/GEOS_RAJA_Interface.hpp" #include "constitutive/fluid/twophasefluid/TwoPhaseFluid.hpp" #include "constitutive/solid/CoupledSolidBase.hpp" +#include "constitutive/ConstitutivePassThru.hpp" #include "constitutive/fluid/twophasefluid/TwoPhaseFluidFields.hpp" #include "constitutive/capillaryPressure/CapillaryPressureFields.hpp" #include "constitutive/capillaryPressure/CapillaryPressureBase.hpp" @@ -50,6 +53,19 @@ namespace geos { namespace immiscibleMultiphaseKernels { + + template< typename VIEWTYPE > +real64 computePCalpha ( real64 S ) { + real64 Pe = Pe_max; + return (Pe * (1.0 - S)); +} + +template< typename VIEWTYPE > +real64 computePCalphaInv ( real64 Pc ) { + real64 Pe = Pe_max; + return (1.0 - Pc / Pe); +} + using namespace constitutive; @@ -406,6 +422,7 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase real64 dGravHead_dP[numEqn][2]{}; real64 capGrad[numEqn]{}; + real64 capPresIC[numEqn][2]{}; real64 dCapGrad_dP[numEqn][2]{}; real64 dCapGrad_dS[numEqn][2]{}; @@ -417,6 +434,13 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase real64 dMob_dP[numEqn][2]{}; real64 dMob_dS[numEqn][2]{}; + real64 density2[numEqn]{}; + real64 dDens_dP2[numEqn][2]{}; + + real64 uT = 0; + real64 duT_dP[numEqn]{}; + real64 duT_dS[numEqn]{}; + real64 const trans[2] = { stack.transmissibility[connectionIndex][0], stack.transmissibility[connectionIndex][1] }; real64 const dTrans_dP[2] = { stack.dTrans_dPres[connectionIndex][0], stack.dTrans_dPres[connectionIndex][1] }; @@ -492,6 +516,7 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase if( m_hasCapPressure ) // check sign convention { real64 const capPres = m_phaseCapPressure[er][esr][ei][0][ip]; // Pc = Pc1 || Pc2 + capPresIC[ip][ke] = capPres; dCapGrad_dTrans -= signPotDiff[ke] * capPres; // dDPc/dT = (-Pc1 + Pc2) pot -= trans[ke] * capPres; // Phi = T P1 - rho T g z1 - T Pc1 || -T P2 + rho T g z2 + T // Pc2 @@ -543,6 +568,8 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase localIndex const k_up = 1 - localIndex( fmax( fmin( alpha, 1.0 ), 0.0 ) ); // 1 upwind -> k_up = 0 || 2 upwind -> k_up = 1 mobility[ip] = m_mob[seri[k_up]][sesri[k_up]][sei[k_up]][ip]; // M = Mupstream + density2[ip] = m_dens[seri[k_up]][sesri[k_up]][sei[k_up]][0][ip]; // r = rho1 || rho2 + dDens_dP2[ip][k_up] = m_dDens_dPres[seri[k_up]][sesri[k_up]][sei[k_up]][0][ip][Deriv::dP]; // dr/dP = dr1/dP1 || dr2/dP dMob_dP[ip][k_up] = m_dMob[seri[k_up]][sesri[k_up]][sei[k_up]][ip][Deriv::dP]; // dM/dP = {dM/dP1 , 0} OR {0 , dM/dP2} dMob_dS[ip][k_up] = m_dMob[seri[k_up]][sesri[k_up]][sei[k_up]][ip][Deriv::dS]; // dM/dS = {dM/dS1 , 0} OR {0 , dM/dS2} } @@ -552,6 +579,8 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase for( integer ke = 0; ke < 2; ++ke ) { mobility[ip] += mobWeights[ke] * m_mob[seri[ke]][sesri[ke]][sei[ke]][ip]; // M = alpha * M1 + (1 - alpha) * M2 + density2[ip] += mobWeights[ke] * m_dens[seri[ke]][sesri[ke]][sei[ke]][0][ip]; // r = rho1 || rho2 + dDens_dP2[ip][ke] = mobWeights[ke] * m_dDens_dPres[seri[ke]][sesri[ke]][sei[ke]][0][ip][Deriv::dP]; // dr/dP = dr1/dP1 || dr2/dP dMob_dP[ip][ke] = mobWeights[ke] * m_dMob[seri[ke]][sesri[ke]][sei[ke]][ip][Deriv::dP]; // dM/dP = {alpha * dM1/dP1 , (1 - // alpha) * dM2/dP2} dMob_dS[ip][ke] = mobWeights[ke] * m_dMob[seri[ke]][sesri[ke]][sei[ke]][ip][Deriv::dS]; // dM/dP = {alpha * dM1/dS1 , (1 - @@ -609,11 +638,23 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase // rho g (z1 - z2) + dT/dP1 * (-Pc1 + Pc2)] + dM/dP1 * DPhi , // M [-T + dT/dP2 * (P1 - P2) - drho2/dP * T g (z1 - z2) - dT/dP2 * // rho g (z1 - z2) + dT/dP2 * (-Pc1 + Pc2)] + dM/dP2 * DPhi } - dFlux_dS[ip][ke] += dMob_dS[ip][ke] * potGrad; // dF/dS = { M [T * -dPc/dS1] + dM/dS1 * DPhi , M [T * dPc/dS2] + dM/dS2 * DPhi // } } + uT += fluxVal[ip] / density2[ip]; + + // add contribution from upstream cell mobility derivatives + for( integer ke = 0; ke < 2; ++ke ) + { + duT_dP[ke] += dFlux_dP[ip][ke] - fluxVal[ip] * dDens_dP2[ip][ke] / density2[ip]; // dF/dP = { M [ T + dT/dP1 * (P1 - P2) - drho1/dP * T g (z1 - z2) - dT/dP1 * + duT_dP[ke] /= density2[ip]; // rho g (z1 - z2) + dT/dP1 * (-Pc1 + Pc2)] + dM/dP1 * DPhi , + // M [-T + dT/dP2 * (P1 - P2) - drho2/dP * T g (z1 - z2) - dT/dP2 * + // rho g (z1 - z2) + dT/dP2 * (-Pc1 + Pc2)] + dM/dP2 * DPhi } + duT_dS[ke] += dFlux_dS[ip][ke] / density2[ip]; // dF/dS = { M [T * -dPc/dS1] + dM/dS1 * DPhi , M [T * dPc/dS2] + dM/dS2 * DPhi + // } + } + // populate local flux vector and derivatives stack.localFlux[k[0]*numEqn + ip] += m_dt * fluxVal[ip]; stack.localFlux[k[1]*numEqn + ip] -= m_dt * fluxVal[ip]; @@ -633,9 +674,43 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase // Customize the kernel with this lambda kernelOp( k, seri, sesri, sei, connectionIndex, alpha, mobility, potGrad, fluxVal, dFlux_dP, dFlux_dS ); // Not sure what this - // does + + // does } // loop over phases + + if( m_hasCapPressure ) + { + // std::cout << GEOS_FMT( " uT = ( {:4.2e} )", uT ); + // std::cout << GEOS_FMT( " duTdP = ( {:4.2e} )", duT_dP[0] ); + // std::cout << GEOS_FMT( " duTdS = ( {:4.2e} )", duT_dS[0] ); + std::cout << GEOS_FMT( " Pc1 = ( {:4.2e} )", capPresIC[0][0] ); + std::cout << GEOS_FMT( " Pc2 = ( {:4.2e} )", capPresIC[0][1] ); + + + + // -------------------- Here I implement the interface conditions local solver --------------------- // + // initial guess: + real64 S_int[numEqn]{}; + real64 const Pc1 = capPresIC[0][0]; + real64 const Pc2 = capPresIC[0][1]; + + real64 const Pc_int = ( Pc1 + Pc2 ) / 2; + + // Local newton loop: + + // compute S_alpha and S_beta: + S_int[0] = computePCalphaInv > ( Pc_int ); + S_int[1] = computePCalphaInv > ( Pc_int ); + + real64 S_avg = S_int[0] + S_int[1]; + + // real64 PC_int1 = computePCalphaInv > ( S_int[0] ); + // real64 PC_int2 = computePCalphaInv > ( S_int[1] ); + GEOS_UNUSED_PARAM( S_avg ); + + } + connectionIndex++; } @@ -762,6 +837,7 @@ class FaceBasedAssemblyKernelFactory globalIndex const rankOffset, string const & dofKey, integer const hasCapPressure, + CapillaryPressureBase const & capPressure, integer const useTotalMassEquation, integer const checkPhasePresenceInGravity, string const & solverName, @@ -771,6 +847,14 @@ class FaceBasedAssemblyKernelFactory CRSMatrixView< real64, globalIndex const > const & localMatrix, arrayView1d< real64 > const & localRhs ) { + // constitutiveUpdatePassThru( capPressure, [&] ( auto & castedCapPres ) + // { + // typename TYPEOFREF( castedCapPres ) ::KernelWrapper const & capPresWrapper = castedCapPres.createKernelWrapper(); + // isothermalCompositionalMultiphaseBaseKernels:: + // CapillaryPressureUpdateKernel:: + // launch< parallelDevicePolicy<> >( dataGroup.size(), + // capPresWrapper, + // phaseVolFrac ); integer constexpr NUM_EQN = 2; integer constexpr NUM_DOF = 2; @@ -789,6 +873,7 @@ class FaceBasedAssemblyKernelFactory dt, localMatrix, localRhs, hasCapPressure, useTotalMassEquation, checkPhasePresenceInGravity ); kernelType::template launch< POLICY >( stencilWrapper.size(), kernel ); + // } ); } }; From 9ff577e7f5dfaa2be418a0139e54aac83d98e6b0 Mon Sep 17 00:00:00 2001 From: Pavel Tomin Date: Fri, 28 Feb 2025 10:12:28 -0600 Subject: [PATCH 089/102] code style --- .../fluidFlow/ImmiscibleMultiphaseFlow.cpp | 63 +++++++-------- .../ImmiscibleMultiphaseKernels.hpp | 78 ++++++++++--------- 2 files changed, 71 insertions(+), 70 deletions(-) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp index 8b70e4bba44..1e34d659d6c 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp @@ -618,41 +618,38 @@ void ImmiscibleMultiphaseFlow::assembleFluxTerms( real64 const dt, MeshLevel const & mesh, string_array const & regionNames ) { - - - fluxApprox.forAllStencils( mesh, [&]( auto & stencil ) { - mesh.getElemManager().forElementSubRegions( regionNames, - [&]( localIndex const, - ElementSubRegionBase const & subRegion ) - { - // if( m_hasCapPressure ) - // { - string const & cappresName = subRegion.getReference< string >( viewKeyStruct::capPressureNamesString() ); - CapillaryPressureBase const & capPressure = getConstitutiveModel< CapillaryPressureBase >( subRegion, cappresName ); - // constitutive::constitutiveUpdatePassThru( capPressure, [&] ( auto & castedCapPres ) - // { - // typename TYPEOFREF( castedCapPres ) ::KernelWrapper capPresWrapper = castedCapPres.createKernelWrapper(); - // } ); - // } - - typename TYPEOFREF( stencil ) ::KernelWrapper stencilWrapper = stencil.createKernelWrapper(); - immiscibleMultiphaseKernels:: - FaceBasedAssemblyKernelFactory::createAndLaunch< parallelDevicePolicy<> >( m_numPhases, - dofManager.rankOffset(), - dofKey, - m_hasCapPressure, - capPressure, - m_useTotalMassEquation, - m_gravityDensityScheme == GravityDensityScheme::PhasePresence, - getName(), - mesh.getElemManager(), - stencilWrapper, - dt, - localMatrix.toViewConstSizes(), - localRhs.toView() ); - } ); + mesh.getElemManager().forElementSubRegions( regionNames, + [&]( localIndex const, + ElementSubRegionBase const & subRegion ) + { + // if( m_hasCapPressure ) + // { + string const & cappresName = subRegion.getReference< string >( viewKeyStruct::capPressureNamesString() ); + CapillaryPressureBase const & capPressure = getConstitutiveModel< CapillaryPressureBase >( subRegion, cappresName ); + // constitutive::constitutiveUpdatePassThru( capPressure, [&] ( auto & castedCapPres ) + // { + // typename TYPEOFREF( castedCapPres ) ::KernelWrapper capPresWrapper = castedCapPres.createKernelWrapper(); + // } ); + // } + + typename TYPEOFREF( stencil ) ::KernelWrapper stencilWrapper = stencil.createKernelWrapper(); + immiscibleMultiphaseKernels:: + FaceBasedAssemblyKernelFactory::createAndLaunch< parallelDevicePolicy<> >( m_numPhases, + dofManager.rankOffset(), + dofKey, + m_hasCapPressure, + capPressure, + m_useTotalMassEquation, + m_gravityDensityScheme == GravityDensityScheme::PhasePresence, + getName(), + mesh.getElemManager(), + stencilWrapper, + dt, + localMatrix.toViewConstSizes(), + localRhs.toView() ); + } ); } ); } ); } diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp index 160f806d48d..1318f869e75 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp @@ -54,14 +54,16 @@ namespace geos namespace immiscibleMultiphaseKernels { - template< typename VIEWTYPE > -real64 computePCalpha ( real64 S ) { +template< typename VIEWTYPE > +real64 computePCalpha ( real64 S ) +{ real64 Pe = Pe_max; return (Pe * (1.0 - S)); } template< typename VIEWTYPE > -real64 computePCalphaInv ( real64 Pc ) { +real64 computePCalphaInv ( real64 Pc ) +{ real64 Pe = Pe_max; return (1.0 - Pc / Pe); } @@ -580,7 +582,8 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase { mobility[ip] += mobWeights[ke] * m_mob[seri[ke]][sesri[ke]][sei[ke]][ip]; // M = alpha * M1 + (1 - alpha) * M2 density2[ip] += mobWeights[ke] * m_dens[seri[ke]][sesri[ke]][sei[ke]][0][ip]; // r = rho1 || rho2 - dDens_dP2[ip][ke] = mobWeights[ke] * m_dDens_dPres[seri[ke]][sesri[ke]][sei[ke]][0][ip][Deriv::dP]; // dr/dP = dr1/dP1 || dr2/dP + dDens_dP2[ip][ke] = mobWeights[ke] * m_dDens_dPres[seri[ke]][sesri[ke]][sei[ke]][0][ip][Deriv::dP]; // dr/dP = dr1/dP1 || + // dr2/dP dMob_dP[ip][ke] = mobWeights[ke] * m_dMob[seri[ke]][sesri[ke]][sei[ke]][ip][Deriv::dP]; // dM/dP = {alpha * dM1/dP1 , (1 - // alpha) * dM2/dP2} dMob_dS[ip][ke] = mobWeights[ke] * m_dMob[seri[ke]][sesri[ke]][sei[ke]][ip][Deriv::dS]; // dM/dP = {alpha * dM1/dS1 , (1 - @@ -642,15 +645,16 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase // } } - uT += fluxVal[ip] / density2[ip]; + uT += fluxVal[ip] / density2[ip]; // add contribution from upstream cell mobility derivatives for( integer ke = 0; ke < 2; ++ke ) { - duT_dP[ke] += dFlux_dP[ip][ke] - fluxVal[ip] * dDens_dP2[ip][ke] / density2[ip]; // dF/dP = { M [ T + dT/dP1 * (P1 - P2) - drho1/dP * T g (z1 - z2) - dT/dP1 * + duT_dP[ke] += dFlux_dP[ip][ke] - fluxVal[ip] * dDens_dP2[ip][ke] / density2[ip]; // dF/dP = { M [ T + dT/dP1 * (P1 - P2) - + // drho1/dP * T g (z1 - z2) - dT/dP1 * duT_dP[ke] /= density2[ip]; // rho g (z1 - z2) + dT/dP1 * (-Pc1 + Pc2)] + dM/dP1 * DPhi , - // M [-T + dT/dP2 * (P1 - P2) - drho2/dP * T g (z1 - z2) - dT/dP2 * - // rho g (z1 - z2) + dT/dP2 * (-Pc1 + Pc2)] + dM/dP2 * DPhi } + // M [-T + dT/dP2 * (P1 - P2) - drho2/dP * T g (z1 - z2) - dT/dP2 * + // rho g (z1 - z2) + dT/dP2 * (-Pc1 + Pc2)] + dM/dP2 * DPhi } duT_dS[ke] += dFlux_dS[ip][ke] / density2[ip]; // dF/dS = { M [T * -dPc/dS1] + dM/dS1 * DPhi , M [T * dPc/dS2] + dM/dS2 * DPhi // } } @@ -674,42 +678,42 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase // Customize the kernel with this lambda kernelOp( k, seri, sesri, sei, connectionIndex, alpha, mobility, potGrad, fluxVal, dFlux_dP, dFlux_dS ); // Not sure what this - - // does + + // does } // loop over phases - + if( m_hasCapPressure ) - { - // std::cout << GEOS_FMT( " uT = ( {:4.2e} )", uT ); - // std::cout << GEOS_FMT( " duTdP = ( {:4.2e} )", duT_dP[0] ); - // std::cout << GEOS_FMT( " duTdS = ( {:4.2e} )", duT_dS[0] ); - std::cout << GEOS_FMT( " Pc1 = ( {:4.2e} )", capPresIC[0][0] ); - std::cout << GEOS_FMT( " Pc2 = ( {:4.2e} )", capPresIC[0][1] ); + { + // std::cout << GEOS_FMT( " uT = ( {:4.2e} )", uT ); + // std::cout << GEOS_FMT( " duTdP = ( {:4.2e} )", duT_dP[0] ); + // std::cout << GEOS_FMT( " duTdS = ( {:4.2e} )", duT_dS[0] ); + std::cout << GEOS_FMT( " Pc1 = ( {:4.2e} )", capPresIC[0][0] ); + std::cout << GEOS_FMT( " Pc2 = ( {:4.2e} )", capPresIC[0][1] ); - // -------------------- Here I implement the interface conditions local solver --------------------- // - // initial guess: - real64 S_int[numEqn]{}; - real64 const Pc1 = capPresIC[0][0]; - real64 const Pc2 = capPresIC[0][1]; + // -------------------- Here I implement the interface conditions local solver --------------------- // + // initial guess: + real64 S_int[numEqn]{}; + real64 const Pc1 = capPresIC[0][0]; + real64 const Pc2 = capPresIC[0][1]; - real64 const Pc_int = ( Pc1 + Pc2 ) / 2; + real64 const Pc_int = ( Pc1 + Pc2 ) / 2; - // Local newton loop: + // Local newton loop: - // compute S_alpha and S_beta: - S_int[0] = computePCalphaInv > ( Pc_int ); - S_int[1] = computePCalphaInv > ( Pc_int ); + // compute S_alpha and S_beta: + S_int[0] = computePCalphaInv< arrayView1d< real64 const > >( Pc_int ); + S_int[1] = computePCalphaInv< arrayView1d< real64 const > >( Pc_int ); - real64 S_avg = S_int[0] + S_int[1]; + real64 S_avg = S_int[0] + S_int[1]; - // real64 PC_int1 = computePCalphaInv > ( S_int[0] ); - // real64 PC_int2 = computePCalphaInv > ( S_int[1] ); - GEOS_UNUSED_PARAM( S_avg ); + // real64 PC_int1 = computePCalphaInv > ( S_int[0] ); + // real64 PC_int2 = computePCalphaInv > ( S_int[1] ); + GEOS_UNUSED_PARAM( S_avg ); - } + } connectionIndex++; @@ -850,11 +854,11 @@ class FaceBasedAssemblyKernelFactory // constitutiveUpdatePassThru( capPressure, [&] ( auto & castedCapPres ) // { // typename TYPEOFREF( castedCapPres ) ::KernelWrapper const & capPresWrapper = castedCapPres.createKernelWrapper(); - // isothermalCompositionalMultiphaseBaseKernels:: - // CapillaryPressureUpdateKernel:: - // launch< parallelDevicePolicy<> >( dataGroup.size(), - // capPresWrapper, - // phaseVolFrac ); + // isothermalCompositionalMultiphaseBaseKernels:: + // CapillaryPressureUpdateKernel:: + // launch< parallelDevicePolicy<> >( dataGroup.size(), + // capPresWrapper, + // phaseVolFrac ); integer constexpr NUM_EQN = 2; integer constexpr NUM_DOF = 2; From 2a25e7bdd994ef454b7c5922c742374ffdbede1c Mon Sep 17 00:00:00 2001 From: Pavel Tomin Date: Fri, 28 Feb 2025 11:03:47 -0600 Subject: [PATCH 090/102] try this --- .../fluidFlow/ImmiscibleMultiphaseFlow.cpp | 49 +- .../fluidFlow/ImmiscibleMultiphaseFlow.hpp | 11 +- .../ImmiscibleMultiphaseKernels.hpp | 566 +++++++++++++++--- 3 files changed, 533 insertions(+), 93 deletions(-) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp index 1e34d659d6c..78afa888ba6 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp @@ -600,7 +600,7 @@ void ImmiscibleMultiphaseFlow::assembleAccumulationTerm( DomainPartition & domai } void ImmiscibleMultiphaseFlow::assembleFluxTerms( real64 const dt, - DomainPartition const & domain, + DomainPartition & domain, DofManager const & dofManager, CRSMatrixView< real64, globalIndex const > const & localMatrix, arrayView1d< real64 > const & localRhs ) const @@ -615,32 +615,52 @@ void ImmiscibleMultiphaseFlow::assembleFluxTerms( real64 const dt, forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&] ( string const &, - MeshLevel const & mesh, + MeshLevel & mesh, string_array const & regionNames ) { - fluxApprox.forAllStencils( mesh, [&]( auto & stencil ) + if( m_hasCapPressure ) { mesh.getElemManager().forElementSubRegions( regionNames, [&]( localIndex const, - ElementSubRegionBase const & subRegion ) + ElementSubRegionBase & subRegion ) { - // if( m_hasCapPressure ) - // { string const & cappresName = subRegion.getReference< string >( viewKeyStruct::capPressureNamesString() ); - CapillaryPressureBase const & capPressure = getConstitutiveModel< CapillaryPressureBase >( subRegion, cappresName ); - // constitutive::constitutiveUpdatePassThru( capPressure, [&] ( auto & castedCapPres ) - // { - // typename TYPEOFREF( castedCapPres ) ::KernelWrapper capPresWrapper = castedCapPres.createKernelWrapper(); - // } ); - // } + CapillaryPressureBase & capPressure = getConstitutiveModel< CapillaryPressureBase >( subRegion, cappresName ); + constitutive::constitutiveUpdatePassThru( capPressure, [&] ( auto & castedCapPres ) + { + typename TYPEOFREF( castedCapPres ) ::KernelWrapper capPresWrapper = castedCapPres.createKernelWrapper(); + fluxApprox.forAllStencils( mesh, [&]( auto & stencil ) + { + typename TYPEOFREF( stencil ) ::KernelWrapper stencilWrapper = stencil.createKernelWrapper(); + immiscibleMultiphaseKernels:: + FaceBasedAssemblyKernelFactory::createAndLaunch< parallelDevicePolicy<> >( m_numPhases, + dofManager.rankOffset(), + dofKey, + m_hasCapPressure, + m_useTotalMassEquation, + m_gravityDensityScheme == GravityDensityScheme::PhasePresence, + getName(), + mesh.getElemManager(), + stencilWrapper, + capPresWrapper, + dt, + localMatrix.toViewConstSizes(), + localRhs.toView() ); + } ); + } ); + } ); + } + else + { + fluxApprox.forAllStencils( mesh, [&]( auto & stencil ) + { typename TYPEOFREF( stencil ) ::KernelWrapper stencilWrapper = stencil.createKernelWrapper(); immiscibleMultiphaseKernels:: FaceBasedAssemblyKernelFactory::createAndLaunch< parallelDevicePolicy<> >( m_numPhases, dofManager.rankOffset(), dofKey, m_hasCapPressure, - capPressure, m_useTotalMassEquation, m_gravityDensityScheme == GravityDensityScheme::PhasePresence, getName(), @@ -650,7 +670,8 @@ void ImmiscibleMultiphaseFlow::assembleFluxTerms( real64 const dt, localMatrix.toViewConstSizes(), localRhs.toView() ); } ); - } ); + } + } ); } diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp index 5d876f9cfd7..feca5e497d0 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp @@ -160,12 +160,11 @@ class ImmiscibleMultiphaseFlow : public FlowSolverBase * @param matrix the system matrix * @param rhs the system right-hand side vector */ - virtual void - assembleFluxTerms( real64 const dt, - DomainPartition const & domain, - DofManager const & dofManager, - CRSMatrixView< real64, globalIndex const > const & localMatrix, - arrayView1d< real64 > const & localRhs ) const; + void assembleFluxTerms( real64 const dt, + DomainPartition & domain, + DofManager const & dofManager, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) const; /** * @brief Function to perform the Application of Dirichlet type BC's diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp index 1318f869e75..ef3b45ce09b 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp @@ -424,7 +424,6 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase real64 dGravHead_dP[numEqn][2]{}; real64 capGrad[numEqn]{}; - real64 capPresIC[numEqn][2]{}; real64 dCapGrad_dP[numEqn][2]{}; real64 dCapGrad_dS[numEqn][2]{}; @@ -436,13 +435,6 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase real64 dMob_dP[numEqn][2]{}; real64 dMob_dS[numEqn][2]{}; - real64 density2[numEqn]{}; - real64 dDens_dP2[numEqn][2]{}; - - real64 uT = 0; - real64 duT_dP[numEqn]{}; - real64 duT_dS[numEqn]{}; - real64 const trans[2] = { stack.transmissibility[connectionIndex][0], stack.transmissibility[connectionIndex][1] }; real64 const dTrans_dP[2] = { stack.dTrans_dPres[connectionIndex][0], stack.dTrans_dPres[connectionIndex][1] }; @@ -518,7 +510,6 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase if( m_hasCapPressure ) // check sign convention { real64 const capPres = m_phaseCapPressure[er][esr][ei][0][ip]; // Pc = Pc1 || Pc2 - capPresIC[ip][ke] = capPres; dCapGrad_dTrans -= signPotDiff[ke] * capPres; // dDPc/dT = (-Pc1 + Pc2) pot -= trans[ke] * capPres; // Phi = T P1 - rho T g z1 - T Pc1 || -T P2 + rho T g z2 + T // Pc2 @@ -570,8 +561,6 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase localIndex const k_up = 1 - localIndex( fmax( fmin( alpha, 1.0 ), 0.0 ) ); // 1 upwind -> k_up = 0 || 2 upwind -> k_up = 1 mobility[ip] = m_mob[seri[k_up]][sesri[k_up]][sei[k_up]][ip]; // M = Mupstream - density2[ip] = m_dens[seri[k_up]][sesri[k_up]][sei[k_up]][0][ip]; // r = rho1 || rho2 - dDens_dP2[ip][k_up] = m_dDens_dPres[seri[k_up]][sesri[k_up]][sei[k_up]][0][ip][Deriv::dP]; // dr/dP = dr1/dP1 || dr2/dP dMob_dP[ip][k_up] = m_dMob[seri[k_up]][sesri[k_up]][sei[k_up]][ip][Deriv::dP]; // dM/dP = {dM/dP1 , 0} OR {0 , dM/dP2} dMob_dS[ip][k_up] = m_dMob[seri[k_up]][sesri[k_up]][sei[k_up]][ip][Deriv::dS]; // dM/dS = {dM/dS1 , 0} OR {0 , dM/dS2} } @@ -581,9 +570,6 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase for( integer ke = 0; ke < 2; ++ke ) { mobility[ip] += mobWeights[ke] * m_mob[seri[ke]][sesri[ke]][sei[ke]][ip]; // M = alpha * M1 + (1 - alpha) * M2 - density2[ip] += mobWeights[ke] * m_dens[seri[ke]][sesri[ke]][sei[ke]][0][ip]; // r = rho1 || rho2 - dDens_dP2[ip][ke] = mobWeights[ke] * m_dDens_dPres[seri[ke]][sesri[ke]][sei[ke]][0][ip][Deriv::dP]; // dr/dP = dr1/dP1 || - // dr2/dP dMob_dP[ip][ke] = mobWeights[ke] * m_dMob[seri[ke]][sesri[ke]][sei[ke]][ip][Deriv::dP]; // dM/dP = {alpha * dM1/dP1 , (1 - // alpha) * dM2/dP2} dMob_dS[ip][ke] = mobWeights[ke] * m_dMob[seri[ke]][sesri[ke]][sei[ke]][ip][Deriv::dS]; // dM/dP = {alpha * dM1/dS1 , (1 - @@ -641,21 +627,8 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase // rho g (z1 - z2) + dT/dP1 * (-Pc1 + Pc2)] + dM/dP1 * DPhi , // M [-T + dT/dP2 * (P1 - P2) - drho2/dP * T g (z1 - z2) - dT/dP2 * // rho g (z1 - z2) + dT/dP2 * (-Pc1 + Pc2)] + dM/dP2 * DPhi } - dFlux_dS[ip][ke] += dMob_dS[ip][ke] * potGrad; // dF/dS = { M [T * -dPc/dS1] + dM/dS1 * DPhi , M [T * dPc/dS2] + dM/dS2 * DPhi - // } - } - - uT += fluxVal[ip] / density2[ip]; - // add contribution from upstream cell mobility derivatives - for( integer ke = 0; ke < 2; ++ke ) - { - duT_dP[ke] += dFlux_dP[ip][ke] - fluxVal[ip] * dDens_dP2[ip][ke] / density2[ip]; // dF/dP = { M [ T + dT/dP1 * (P1 - P2) - - // drho1/dP * T g (z1 - z2) - dT/dP1 * - duT_dP[ke] /= density2[ip]; // rho g (z1 - z2) + dT/dP1 * (-Pc1 + Pc2)] + dM/dP1 * DPhi , - // M [-T + dT/dP2 * (P1 - P2) - drho2/dP * T g (z1 - z2) - dT/dP2 * - // rho g (z1 - z2) + dT/dP2 * (-Pc1 + Pc2)] + dM/dP2 * DPhi } - duT_dS[ke] += dFlux_dS[ip][ke] / density2[ip]; // dF/dS = { M [T * -dPc/dS1] + dM/dS1 * DPhi , M [T * dPc/dS2] + dM/dS2 * DPhi + dFlux_dS[ip][ke] += dMob_dS[ip][ke] * potGrad; // dF/dS = { M [T * -dPc/dS1] + dM/dS1 * DPhi , M [T * dPc/dS2] + dM/dS2 * DPhi // } } @@ -678,44 +651,10 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase // Customize the kernel with this lambda kernelOp( k, seri, sesri, sei, connectionIndex, alpha, mobility, potGrad, fluxVal, dFlux_dP, dFlux_dS ); // Not sure what this - - // does + // does } // loop over phases - if( m_hasCapPressure ) - { - // std::cout << GEOS_FMT( " uT = ( {:4.2e} )", uT ); - // std::cout << GEOS_FMT( " duTdP = ( {:4.2e} )", duT_dP[0] ); - // std::cout << GEOS_FMT( " duTdS = ( {:4.2e} )", duT_dS[0] ); - std::cout << GEOS_FMT( " Pc1 = ( {:4.2e} )", capPresIC[0][0] ); - std::cout << GEOS_FMT( " Pc2 = ( {:4.2e} )", capPresIC[0][1] ); - - - - // -------------------- Here I implement the interface conditions local solver --------------------- // - // initial guess: - real64 S_int[numEqn]{}; - real64 const Pc1 = capPresIC[0][0]; - real64 const Pc2 = capPresIC[0][1]; - - real64 const Pc_int = ( Pc1 + Pc2 ) / 2; - - // Local newton loop: - - // compute S_alpha and S_beta: - S_int[0] = computePCalphaInv< arrayView1d< real64 const > >( Pc_int ); - S_int[1] = computePCalphaInv< arrayView1d< real64 const > >( Pc_int ); - - real64 S_avg = S_int[0] + S_int[1]; - - // real64 PC_int1 = computePCalphaInv > ( S_int[0] ); - // real64 PC_int2 = computePCalphaInv > ( S_int[1] ); - GEOS_UNUSED_PARAM( S_avg ); - - } - - connectionIndex++; } } // loop over connection elements @@ -812,6 +751,446 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase typename STENCILWRAPPER::IndexContainerViewConstType const m_sei; }; +/** + * @class FaceBasedAssemblyInterfaceConditionKernel + * @tparam NUM_DOF number of degrees of freedom + * @tparam STENCILWRAPPER the type of the stencil wrapper + * @tparam CAPPRESWRAPPER the type of the capillary pressure wrapper + * @brief Define the interface for the assembly kernel in charge of flux terms + */ +template< integer NUM_EQN, integer NUM_DOF, typename STENCILWRAPPER, typename CAPPRESWRAPPER > +class FaceBasedAssemblyInterfaceConditionKernel : public FaceBasedAssemblyKernel< NUM_EQN, NUM_DOF, STENCILWRAPPER > +{ +public: + + using AbstractBase = FaceBasedAssemblyKernelBase; + using DofNumberAccessor = AbstractBase::DofNumberAccessor; + using ImmiscibleMultiphaseFlowAccessors = AbstractBase::ImmiscibleMultiphaseFlowAccessors; + using MultiphaseFluidAccessors = AbstractBase::MultiphaseFluidAccessors; + using CapPressureAccessors = AbstractBase::CapPressureAccessors; + using PermeabilityAccessors = AbstractBase::PermeabilityAccessors; + + using Base = FaceBasedAssemblyKernel< NUM_EQN, NUM_DOF, STENCILWRAPPER >; + using Deriv = typename Base::Deriv; + using StackVariables = typename Base::StackVariables; + using Base::numEqn; + using Base::numDof; + using Base::m_stencilWrapper; + using Base::m_dofNumber; + using Base::m_rankOffset; + using Base::m_localMatrix; + using Base::m_localRhs; + using Base::m_numPhases; + using Base::m_permeability; + using Base::m_dPerm_dPres; + using Base::m_phaseVolFrac; + using Base::m_phaseCapPressure; + using Base::m_dPhaseCapPressure_dPhaseVolFrac; + using Base::m_dens; + using Base::m_dDens_dPres; + using Base::m_dMob; + using Base::m_mob; + using Base::m_gravCoef; + using Base::m_ghostRank; + using Base::m_dt; + using Base::m_hasCapPressure; + using Base::m_useTotalMassEquation; + using Base::m_checkPhasePresenceInGravity; + using Base::m_seri; + using Base::m_sesri; + using Base::m_sei; + using Base::m_pres; + + /** + * @brief Constructor for the kernel interface + * @param[in] numPhases number of fluid phases + * @param[in] rankOffset the offset of my MPI rank + * @param[in] stencilWrapper reference to the stencil wrapper + * @param[in] capPressureWrapper reference to the capillary pressure wrapper + * @param[in] dofNumberAccessor + * @param[in] multiPhaseFlowAccessors + * @param[in] fluidAccessors + * @param[in] capPressureAccessors + * @param[in] permeabilityAccessors + * @param[in] dt time step size + * @param[inout] localMatrix the local CRS matrix + * @param[inout] localRhs the local right-hand side vector + * @param[in] hasCapPressure flags for capillary pressure + * @param[in] useTotalMassEquation flags for using total velocity formulation + */ + FaceBasedAssemblyInterfaceConditionKernel( integer const numPhases, + globalIndex const rankOffset, + STENCILWRAPPER const & stencilWrapper, + CAPPRESWRAPPER const & capPressureWrapper, + DofNumberAccessor const & dofNumberAccessor, + ImmiscibleMultiphaseFlowAccessors const & multiPhaseFlowAccessors, + MultiphaseFluidAccessors const & fluidAccessors, + CapPressureAccessors const & capPressureAccessors, + PermeabilityAccessors const & permeabilityAccessors, + real64 const & dt, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs, + integer const hasCapPressure, + integer const useTotalMassEquation, + integer const checkPhasePresenceInGravity ) + : Base( numPhases, + rankOffset, + stencilWrapper, + dofNumberAccessor, + multiPhaseFlowAccessors, + fluidAccessors, + capPressureAccessors, + permeabilityAccessors, + dt, + localMatrix, + localRhs, + hasCapPressure, + useTotalMassEquation, + checkPhasePresenceInGravity ), + m_capPressureWrapper( capPressureWrapper ) + {} + + /** + * @brief Compute the local flux contributions to the residual and Jacobian + * @tparam FUNC the type of the function that can be used to customize the computation of the flux + * @param[in] iconn the connection index + * @param[inout] stack the stack variables + * @param[in] NoOpFunc the function used to customize the computation of the flux + */ + template< typename FUNC = NoOpFunc > // should change to multiphase + GEOS_HOST_DEVICE + void computeFlux( localIndex const iconn, + StackVariables & stack, + FUNC && kernelOp = NoOpFunc{} ) const + { + // first, compute the transmissibilities at this face // get k and dk/dP from global arrays + // and place in stack + m_stencilWrapper.computeWeights( iconn, + m_permeability, + m_dPerm_dPres, + stack.transmissibility, + stack.dTrans_dPres ); + + localIndex k[2]; + localIndex connectionIndex = 0; + + for( k[0] = 0; k[0] < stack.numFluxElems; ++k[0] ) + { + for( k[1] = k[0] + 1; k[1] < stack.numFluxElems; ++k[1] ) + { + // clear working arrays + real64 densMean[numEqn]{}; + real64 dDensMean_dP[numEqn][2]{}; + + real64 presGrad[numEqn]{}; + real64 dPresGrad_dP[numEqn][2]{}; + + real64 gravHead[numEqn]{}; + real64 dGravHead_dP[numEqn][2]{}; + + real64 capGrad[numEqn]{}; + real64 capPresIC[numEqn][2]{}; + real64 dCapGrad_dP[numEqn][2]{}; + real64 dCapGrad_dS[numEqn][2]{}; + + real64 fluxVal[numEqn]{}; + real64 dFlux_dP[numEqn][2]{}; + real64 dFlux_dS[numEqn][2]{}; + + real64 mobility[numEqn]{}; + real64 dMob_dP[numEqn][2]{}; + real64 dMob_dS[numEqn][2]{}; + + real64 density2[numEqn]{}; + real64 dDens_dP2[numEqn][2]{}; + + real64 uT = 0; + real64 duT_dP[numEqn]{}; + real64 duT_dS[numEqn]{}; + + real64 const trans[2] = { stack.transmissibility[connectionIndex][0], stack.transmissibility[connectionIndex][1] }; + real64 const dTrans_dP[2] = { stack.dTrans_dPres[connectionIndex][0], stack.dTrans_dPres[connectionIndex][1] }; + + // cell indices + localIndex const seri[2] = {m_seri( iconn, k[0] ), m_seri( iconn, k[1] )}; + localIndex const sesri[2] = {m_sesri( iconn, k[0] ), m_sesri( iconn, k[1] )}; + localIndex const sei[2] = {m_sei( iconn, k[0] ), m_sei( iconn, k[1] )}; + + // loop over phases + for( integer ip = 0; ip < m_numPhases; ++ip ) + { + // calculate quantities on primary connected cells + integer denom = 0; + for( integer ke = 0; ke < 2; ++ke ) + { + // density + bool const phaseExists = (m_phaseVolFrac[seri[ke]][sesri[ke]][sei[ke]][ip] > 0); + if( m_checkPhasePresenceInGravity && !phaseExists ) + { + continue; + } + + real64 const density = m_dens[seri[ke]][sesri[ke]][sei[ke]][0][ip]; // r = rho1 || rho2 + real64 const dDens_dP = m_dDens_dPres[seri[ke]][sesri[ke]][sei[ke]][0][ip][Deriv::dP]; // dr/dP = dr1/dP1 || dr2/dP + + // average density and derivatives + densMean[ip] += density; // rho = (rho1 + rho2) + dDensMean_dP[ip][ke] = dDens_dP; // drho/dP = { (dr1/dP1) , (dr2/dP2) } + + denom++; + } + + if( denom > 1 ) + { + densMean[ip] /= denom; // rho = (rho1 + rho2) / denom + for( integer ke = 0; ke < 2; ++ke ) + { + dDensMean_dP[ip][ke] /= denom; // drho/dP = { (dr1/dP1) / denom , (dr2/dP2) / denom } + } + } + + //***** calculation of flux ***** + + // compute potential difference + real64 potScale = 0.0; + real64 dPresGrad_dTrans = 0.0; + real64 dGravHead_dTrans = 0.0; + real64 dCapGrad_dTrans = 0.0; + constexpr int signPotDiff[2] = {1, -1}; + + for( integer ke = 0; ke < 2; ++ke ) + { + localIndex const er = seri[ke]; + localIndex const esr = sesri[ke]; + localIndex const ei = sei[ke]; + + real64 const pressure = m_pres[er][esr][ei]; // P = P1 || P2 + presGrad[ip] += trans[ke] * pressure; // DPv = T (P1 - P2) + dPresGrad_dTrans += signPotDiff[ke] * pressure; // dDPv/dT = (P1 - P2) + dPresGrad_dP[ip][ke] = trans[ke]; // dDPv/dP = { T , -T } + + real64 const gravD = trans[ke] * m_gravCoef[er][esr][ei]; // D = T g z1 || -T g z2 + real64 pot = trans[ke] * pressure - densMean[ip] * gravD; // Phi = T P1 - rho T g z1 || -T P2 + rho T g z2 + + gravHead[ip] += densMean[ip] * gravD; // DPg = rho (T g z1 - T g z2) = T rho g (z1 - z2) + dGravHead_dTrans += signPotDiff[ke] * densMean[ip] * m_gravCoef[er][esr][ei]; // dDPg/dT = rho g z1 - rho g z2 = rho g (z1 - z2) + + for( integer i = 0; i < 2; ++i ) + { + dGravHead_dP[ip][i] += dDensMean_dP[ip][i] * gravD; // dDPg/dP = {drho/dP1 * T g (z1 - z2) , drho/dP2 * T g (z1 - z2)} + } + + if( m_hasCapPressure ) // check sign convention + { + real64 const capPres = m_phaseCapPressure[er][esr][ei][0][ip]; // Pc = Pc1 || Pc2 + capPresIC[ip][ke] = capPres; + dCapGrad_dTrans -= signPotDiff[ke] * capPres; // dDPc/dT = (-Pc1 + Pc2) + pot -= trans[ke] * capPres; // Phi = T P1 - rho T g z1 - T Pc1 || -T P2 + rho T g z2 + T + // Pc2 + capGrad[ip] -= trans[ke] * capPres; // DPc = T (-Pc1 + Pc2) + } + + potScale = fmax( potScale, fabs( pot ) ); // maxPhi = Phi1 > Phi2 ? Phi1 : Phi2 + } + + for( integer ke = 0; ke < 2; ++ke ) + { + dPresGrad_dP[ip][ke] += dTrans_dP[ke] * dPresGrad_dTrans; // dDPv/dP = { T + dT/dP1 * (P1 - P2) , -T + dT/dP2 * (P1 - P2)} + dGravHead_dP[ip][ke] += dTrans_dP[ke] * dGravHead_dTrans; // dDPg/dP = { drho/dP1 * T g (z1 - z2) + dT/dP1 * rho g (z1 - z2) , + // drho/dP2 * T g (z1 - z2) + dT/dP2 * rho g (z1 - z2) } + if( m_hasCapPressure ) + { + real64 const dCapPres_dS = m_dPhaseCapPressure_dPhaseVolFrac[seri[ke]][sesri[ke]][sei[ke]][0][ip][ip]; // dPc/dS = dPc1/dS1 || + // dPc2/dS2 + dCapGrad_dP[ip][ke] += dTrans_dP[ke] * dCapGrad_dTrans; // dDPc/dP = { dT/dP1 * + // (-Pc1 + Pc2) , + // dT/dP2 * + // (-Pc1 + Pc2) } + dCapGrad_dS[ip][ke] -= trans[ke] * dCapPres_dS; // dDPc/dS = { -T * + // dPc1/dS1 , T * + // dPc2/dS2 } + } + } + + // *** upwinding *** + + // compute potential gradient + real64 potGrad = presGrad[ip] - gravHead[ip]; // DPhi = T (P1 - P2) - T rho g (z1 - z2) + if( m_hasCapPressure ) + { + potGrad += capGrad[ip]; // DPhi = T (P1 - P2) - T rho g (z1 - z2) + T (-Pc1 + Pc2) + } + + // compute upwinding tolerance + real64 constexpr upwRelTol = 1e-8; + real64 const upwAbsTol = fmax( potScale * upwRelTol, LvArray::NumericLimits< real64 >::epsilon ); // abstol = maxPhi * tol > eps ? + // maxPhi * tol : eps + + // decide mobility coefficients - smooth variation in [-upwAbsTol; upwAbsTol] + real64 const alpha = ( potGrad + upwAbsTol ) / ( 2 * upwAbsTol ); // alpha = (DPhi + abstol) / abstol / 2 + + // choose upstream cell + if( alpha <= 0.0 || alpha >= 1.0 ) // no smoothing needed + { + localIndex const k_up = 1 - localIndex( fmax( fmin( alpha, 1.0 ), 0.0 ) ); // 1 upwind -> k_up = 0 || 2 upwind -> k_up = 1 + + mobility[ip] = m_mob[seri[k_up]][sesri[k_up]][sei[k_up]][ip]; // M = Mupstream + density2[ip] = m_dens[seri[k_up]][sesri[k_up]][sei[k_up]][0][ip]; // r = rho1 || rho2 + dDens_dP2[ip][k_up] = m_dDens_dPres[seri[k_up]][sesri[k_up]][sei[k_up]][0][ip][Deriv::dP]; // dr/dP = dr1/dP1 || dr2/dP + dMob_dP[ip][k_up] = m_dMob[seri[k_up]][sesri[k_up]][sei[k_up]][ip][Deriv::dP]; // dM/dP = {dM/dP1 , 0} OR {0 , dM/dP2} + dMob_dS[ip][k_up] = m_dMob[seri[k_up]][sesri[k_up]][sei[k_up]][ip][Deriv::dS]; // dM/dS = {dM/dS1 , 0} OR {0 , dM/dS2} + } + else // perform smoothing + { + real64 const mobWeights[2] = { alpha, 1.0 - alpha }; + for( integer ke = 0; ke < 2; ++ke ) + { + mobility[ip] += mobWeights[ke] * m_mob[seri[ke]][sesri[ke]][sei[ke]][ip]; // M = alpha * M1 + (1 - alpha) * M2 + density2[ip] += mobWeights[ke] * m_dens[seri[ke]][sesri[ke]][sei[ke]][0][ip]; // r = rho1 || rho2 + dDens_dP2[ip][ke] = mobWeights[ke] * m_dDens_dPres[seri[ke]][sesri[ke]][sei[ke]][0][ip][Deriv::dP]; // dr/dP = dr1/dP1 || + // dr2/dP + dMob_dP[ip][ke] = mobWeights[ke] * m_dMob[seri[ke]][sesri[ke]][sei[ke]][ip][Deriv::dP]; // dM/dP = {alpha * dM1/dP1 , (1 - + // alpha) * dM2/dP2} + dMob_dS[ip][ke] = mobWeights[ke] * m_dMob[seri[ke]][sesri[ke]][sei[ke]][ip][Deriv::dS]; // dM/dP = {alpha * dM1/dS1 , (1 - + // alpha) * dM2/dS2} + } + } + + // pressure gradient depends on all points in the stencil + for( integer ke = 0; ke < 2; ++ke ) + { + dFlux_dP[ip][ke] += dPresGrad_dP[ip][ke]; // dF/dP = { T + dT/dP1 * (P1 - P2) , + // -T + dT/dP2 * (P1 - P2) } + } + + // gravitational head depends only on the two cells connected (same as mean density) + for( integer ke = 0; ke < 2; ++ke ) + { + dFlux_dP[ip][ke] -= dGravHead_dP[ip][ke]; // dF/dP = { T + dT/dP1 * (P1 - P2) - drho/dP1 * T g (z1 - z2) - dT/dP1 * rho g (z1 - + // z2) , + // -T + dT/dP2 * (P1 - P2) - drho/dP2 * T g (z1 - z2) - dT/dP2 * rho g (z1 - + // z2) } + } + + // capillary pressure contribution + if( m_hasCapPressure ) + { + for( integer ke = 0; ke < 2; ++ke ) + { + dFlux_dP[ip][ke] += dCapGrad_dP[ip][ke]; // dF/dP = { T + dT/dP1 * (P1 - P2) - drho/dP1 * T g (z1 - z2) - dT/dP1 * rho g (z1 + // - z2) + dT/dP1 * (-Pc1 + Pc2) , + // -T + dT/dP2 * (P1 - P2) - drho/dP2 * T g (z1 - z2) - dT/dP2 * rho g (z1 + // - z2) + dT/dP2 * (-Pc1 + Pc2) } + + dFlux_dS[ip][ke] += dCapGrad_dS[ip][ke]; // dF/dS = { T * -dPc/dS1 , T * dPc/dS2 } + } + } + + // compute the flux and derivatives using upstream cell mobility + fluxVal[ip] = mobility[ip] * potGrad; // F = M * DPhi + + for( integer ke = 0; ke < 2; ++ke ) + { + dFlux_dP[ip][ke] *= mobility[ip]; // dF/dP = { M [ T + dT/dP1 * (P1 - P2) - drho/dP1 * T g (z1 - z2) - dT/dP1 * rho g (z1 - + // z2) + dT/dP1 * (-Pc1 + Pc2)] , + // M [-T + dT/dP2 * (P1 - P2) - drho/dP2 * T g (z1 - z2) - dT/dP2 * rho g (z1 - + // z2) + dT/dP2 * (-Pc1 + Pc2)] } + + dFlux_dS[ip][ke] *= mobility[ip]; // dF/dS = { M [T * -dPc/dS1] , M [T * dPc/dS2] } + } + + // add contribution from upstream cell mobility derivatives + for( integer ke = 0; ke < 2; ++ke ) + { + dFlux_dP[ip][ke] += dMob_dP[ip][ke] * potGrad; // dF/dP = { M [ T + dT/dP1 * (P1 - P2) - drho1/dP * T g (z1 - z2) - dT/dP1 * + // rho g (z1 - z2) + dT/dP1 * (-Pc1 + Pc2)] + dM/dP1 * DPhi , + // M [-T + dT/dP2 * (P1 - P2) - drho2/dP * T g (z1 - z2) - dT/dP2 * + // rho g (z1 - z2) + dT/dP2 * (-Pc1 + Pc2)] + dM/dP2 * DPhi } + dFlux_dS[ip][ke] += dMob_dS[ip][ke] * potGrad; // dF/dS = { M [T * -dPc/dS1] + dM/dS1 * DPhi , M [T * dPc/dS2] + dM/dS2 * DPhi + // } + } + + uT += fluxVal[ip] / density2[ip]; + + // add contribution from upstream cell mobility derivatives + for( integer ke = 0; ke < 2; ++ke ) + { + duT_dP[ke] += dFlux_dP[ip][ke] - fluxVal[ip] * dDens_dP2[ip][ke] / density2[ip]; // dF/dP = { M [ T + dT/dP1 * (P1 - P2) - + // drho1/dP * T g (z1 - z2) - dT/dP1 * + duT_dP[ke] /= density2[ip]; // rho g (z1 - z2) + dT/dP1 * (-Pc1 + Pc2)] + dM/dP1 * DPhi , + // M [-T + dT/dP2 * (P1 - P2) - drho2/dP * T g (z1 - z2) - dT/dP2 * + // rho g (z1 - z2) + dT/dP2 * (-Pc1 + Pc2)] + dM/dP2 * DPhi } + duT_dS[ke] += dFlux_dS[ip][ke] / density2[ip]; // dF/dS = { M [T * -dPc/dS1] + dM/dS1 * DPhi , M [T * dPc/dS2] + dM/dS2 * DPhi + // } + } + + // populate local flux vector and derivatives + stack.localFlux[k[0]*numEqn + ip] += m_dt * fluxVal[ip]; + stack.localFlux[k[1]*numEqn + ip] -= m_dt * fluxVal[ip]; + + for( integer ke = 0; ke < 2; ++ke ) + { + // pressure + localIndex const localDofIndexPres = k[ke] * numDof; + stack.localFluxJacobian[k[0]*numEqn + ip][localDofIndexPres] += m_dt * dFlux_dP[ip][ke]; + stack.localFluxJacobian[k[1]*numEqn + ip][localDofIndexPres] -= m_dt * dFlux_dP[ip][ke]; + + // saturation (hard-coded for 2-phase currently) + localIndex const localDofIndexSat = k[ke] * numDof + 1; + stack.localFluxJacobian[k[0]*numEqn + ip][localDofIndexSat] += m_dt * dFlux_dS[ip][ke]; + stack.localFluxJacobian[k[1]*numEqn + ip][localDofIndexSat] -= m_dt * dFlux_dS[ip][ke]; + } + + // Customize the kernel with this lambda + kernelOp( k, seri, sesri, sei, connectionIndex, alpha, mobility, potGrad, fluxVal, dFlux_dP, dFlux_dS ); // Not sure what this + + // does + + } // loop over phases + + if( m_hasCapPressure ) + { + // std::cout << GEOS_FMT( " uT = ( {:4.2e} )", uT ); + // std::cout << GEOS_FMT( " duTdP = ( {:4.2e} )", duT_dP[0] ); + // std::cout << GEOS_FMT( " duTdS = ( {:4.2e} )", duT_dS[0] ); + std::cout << GEOS_FMT( " Pc1 = ( {:4.2e} )", capPresIC[0][0] ); + std::cout << GEOS_FMT( " Pc2 = ( {:4.2e} )", capPresIC[0][1] ); + + + + // -------------------- Here I implement the interface conditions local solver --------------------- // + // initial guess: + real64 S_int[numEqn]{}; + real64 const Pc1 = capPresIC[0][0]; + real64 const Pc2 = capPresIC[0][1]; + + real64 const Pc_int = ( Pc1 + Pc2 ) / 2; + + // Local newton loop: + + // compute S_alpha and S_beta: + S_int[0] = computePCalphaInv< arrayView1d< real64 const > >( Pc_int ); + S_int[1] = computePCalphaInv< arrayView1d< real64 const > >( Pc_int ); + + real64 S_avg = S_int[0] + S_int[1]; + + // real64 PC_int1 = computePCalphaInv > ( S_int[0] ); + // real64 PC_int2 = computePCalphaInv > ( S_int[1] ); + GEOS_UNUSED_PARAM( S_avg ); + + } + + + connectionIndex++; + } + } // loop over connection elements + } +protected: + + /// Reference to the capillary pressure wrapper + CAPPRESWRAPPER const m_capPressureWrapper; +}; + /****************************************** */ @@ -841,7 +1220,6 @@ class FaceBasedAssemblyKernelFactory globalIndex const rankOffset, string const & dofKey, integer const hasCapPressure, - CapillaryPressureBase const & capPressure, integer const useTotalMassEquation, integer const checkPhasePresenceInGravity, string const & solverName, @@ -851,14 +1229,6 @@ class FaceBasedAssemblyKernelFactory CRSMatrixView< real64, globalIndex const > const & localMatrix, arrayView1d< real64 > const & localRhs ) { - // constitutiveUpdatePassThru( capPressure, [&] ( auto & castedCapPres ) - // { - // typename TYPEOFREF( castedCapPres ) ::KernelWrapper const & capPresWrapper = castedCapPres.createKernelWrapper(); - // isothermalCompositionalMultiphaseBaseKernels:: - // CapillaryPressureUpdateKernel:: - // launch< parallelDevicePolicy<> >( dataGroup.size(), - // capPresWrapper, - // phaseVolFrac ); integer constexpr NUM_EQN = 2; integer constexpr NUM_DOF = 2; @@ -877,7 +1247,57 @@ class FaceBasedAssemblyKernelFactory dt, localMatrix, localRhs, hasCapPressure, useTotalMassEquation, checkPhasePresenceInGravity ); kernelType::template launch< POLICY >( stencilWrapper.size(), kernel ); - // } ); + } + + /** + * @brief Create a new kernel and launch + * @tparam POLICY the policy used in the RAJA kernel + * @tparam STENCILWRAPPER the type of the stencil wrapper + * @tparam CAPPRESWRAPPER the type of the capillary pressure wrapper + * @param[in] rankOffset the offset of my MPI rank + * @param[in] dofKey string to get the element degrees of freedom numbers + * @param[in] solverName name of the solver (to name accessors) + * @param[in] elemManager reference to the element region manager + * @param[in] stencilWrapper reference to the stencil wrapper + * @param[in] capPresWrapper reference to the capillary pressure wrapper + * @param[in] dt time step size + * @param[inout] localMatrix the local CRS matrix + * @param[inout] localRhs the local right-hand side vector + */ + template< typename POLICY, typename STENCILWRAPPER, typename CAPPRESWRAPPER > + static void + createAndLaunch( integer const numPhases, + globalIndex const rankOffset, + string const & dofKey, + integer const hasCapPressure, + integer const useTotalMassEquation, + integer const checkPhasePresenceInGravity, + string const & solverName, + ElementRegionManager const & elemManager, + STENCILWRAPPER const & stencilWrapper, + CAPPRESWRAPPER const & capPresWrapper, + real64 const & dt, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) + { + integer constexpr NUM_EQN = 2; + integer constexpr NUM_DOF = 2; + + ElementRegionManager::ElementViewAccessor< arrayView1d< globalIndex const > > dofNumberAccessor = + elemManager.constructArrayViewAccessor< globalIndex, 1 >( dofKey ); + dofNumberAccessor.setName( solverName + "/accessors/" + dofKey ); + + using kernelType = FaceBasedAssemblyInterfaceConditionKernel< NUM_EQN, NUM_DOF, STENCILWRAPPER, CAPPRESWRAPPER >; + typename kernelType::ImmiscibleMultiphaseFlowAccessors flowAccessors( elemManager, solverName ); + typename kernelType::MultiphaseFluidAccessors fluidAccessors( elemManager, solverName ); + typename kernelType::CapPressureAccessors capPressureAccessors( elemManager, solverName ); + typename kernelType::PermeabilityAccessors permAccessors( elemManager, solverName ); + + kernelType kernel( numPhases, rankOffset, stencilWrapper, capPresWrapper, dofNumberAccessor, + flowAccessors, fluidAccessors, capPressureAccessors, permAccessors, + dt, localMatrix, localRhs, hasCapPressure, useTotalMassEquation, + checkPhasePresenceInGravity ); + kernelType::template launch< POLICY >( stencilWrapper.size(), kernel ); } }; From 28afb1b86e38bf52b4ab32cad06b70f8642f243f Mon Sep 17 00:00:00 2001 From: Ammara-14 Date: Thu, 1 May 2025 21:15:13 -0700 Subject: [PATCH 091/102] first implementation of interface conditions with J-Leverett Pc curve, it compiles with no errors but may not converge --- .../JFunctionCapillaryPressure.cpp | 50 ++ .../JFunctionCapillaryPressure.hpp | 48 ++ .../TableCapillaryPressure.hpp | 28 + .../capillaryPressureSelector.hpp | 12 +- .../finiteVolume/CellElementStencilTPFA.hpp | 98 ++++ .../EmbeddedSurfaceToCellStencil.hpp | 52 ++ .../finiteVolume/FaceElementToCellStencil.hpp | 53 ++ .../finiteVolume/SurfaceElementStencil.hpp | 79 +++ .../fluidFlow/ImmiscibleMultiphaseFlow.cpp | 23 +- .../CapillaryPressureUpdateKernel.hpp | 73 +++ .../ImmiscibleMultiphaseKernels.hpp | 550 ++++++++++++++++-- 11 files changed, 1020 insertions(+), 46 deletions(-) create mode 100644 src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/CapillaryPressureUpdateKernel.hpp diff --git a/src/coreComponents/constitutive/capillaryPressure/JFunctionCapillaryPressure.cpp b/src/coreComponents/constitutive/capillaryPressure/JFunctionCapillaryPressure.cpp index 3e67db4b27b..1a080cb7652 100644 --- a/src/coreComponents/constitutive/capillaryPressure/JFunctionCapillaryPressure.cpp +++ b/src/coreComponents/constitutive/capillaryPressure/JFunctionCapillaryPressure.cpp @@ -120,6 +120,11 @@ JFunctionCapillaryPressure::JFunctionCapillaryPressure( std::string const & name registerWrapper( viewKeyStruct::jFunctionWrappersString(), &m_jFuncKernelWrappers ). setSizedFromParent( 0 ). setRestartFlags( RestartFlags::NO_WRITE ); + + registerWrapper( viewKeyStruct::inverseJFunctionWrappersString(), &m_inverseJFuncKernelWrappers ). + setSizedFromParent( 0 ). + setRestartFlags( RestartFlags::NO_WRITE ); + } void JFunctionCapillaryPressure::postInputInitialization() @@ -185,6 +190,7 @@ void JFunctionCapillaryPressure::initializePreSubGroups() ? true // pc on the gas phase, function must be increasing : false; // pc on the water phase, function must be decreasing TableCapillaryPressureHelpers::validateCapillaryPressureTable( jFuncTable, getFullName(), jFuncMustBeIncreasing ); + } else if( numPhases == 3 ) { @@ -203,6 +209,7 @@ void JFunctionCapillaryPressure::initializePreSubGroups() InputError ); TableFunction const & jFuncTableNWI = functionManager.getGroup< TableFunction >( m_nonWettingIntermediateJFuncTableName ); TableCapillaryPressureHelpers::validateCapillaryPressureTable( jFuncTableNWI, getFullName(), true ); + } } @@ -298,23 +305,64 @@ void JFunctionCapillaryPressure::createAllTableKernelWrappers() // we want to make sure that the wrappers are always up-to-date, so we recreate them everytime m_jFuncKernelWrappers.clear(); + m_inverseJFuncKernelWrappers.clear(); + if( numPhases == 2 ) { + TableFunction const & jFuncTable = functionManager.getGroup< TableFunction >( m_wettingNonWettingJFuncTableName ); m_jFuncKernelWrappers.emplace_back( jFuncTable.createKernelWrapper() ); + + auto const & satArrayView = jFuncTable.getCoordinates()[0]; + auto const & jArrayView = jFuncTable.getValues(); + + std::vector satVec( satArrayView.size() ); + std::vector jVec( jArrayView.size() ); + + std::copy( satArrayView.begin(), satArrayView.end(), satVec.begin() ); + std::copy( jArrayView.begin(), jArrayView.end(), jVec.begin() ); + + // Reverse both arrays (if original J is decreasing in S) +std::reverse( jVec.begin(), jVec.end() ); +std::reverse( satVec.begin(), satVec.end() ); + + +auto inverseTable = std::make_shared( "inverseJFunc", this ); + +real64_array invJVec( jVec.size() ); +real64_array invSatVec( satVec.size() ); +std::copy( jVec.begin(), jVec.end(), invJVec.data() ); +std::copy( satVec.begin(), satVec.end(), invSatVec.data() ); + +array1d< real64_array > coordinates; +coordinates.emplace_back( std::move( invJVec ) ); + + +std::vector< units::Unit > dimUnits = { units::Unknown }; // or actual unit if available + +inverseTable->setTableCoordinates( coordinates, dimUnits ); +inverseTable->setTableValues( std::move( invSatVec ), units::Unknown ); +inverseTable->setInterpolationMethod( TableFunction::InterpolationType::Linear ); + +m_inverseJFuncKernelWrappers.emplace_back( inverseTable->createKernelWrapper() ); +m_inverseTables.emplace_back( std::move( inverseTable ) ); + } else if( numPhases == 3 ) { // the assumption used everywhere in this class is that the WI information comes before the NWI information TableFunction const & jFuncTableWI = functionManager.getGroup< TableFunction >( m_wettingIntermediateJFuncTableName ); m_jFuncKernelWrappers.emplace_back( jFuncTableWI.createKernelWrapper() ); + m_inverseJFuncKernelWrappers.emplace_back( jFuncTableWI.createKernelWrapper() ); TableFunction const & jFuncTableNWI = functionManager.getGroup< TableFunction >( m_nonWettingIntermediateJFuncTableName ); m_jFuncKernelWrappers.emplace_back( jFuncTableNWI.createKernelWrapper() ); + m_inverseJFuncKernelWrappers.emplace_back( jFuncTableNWI.createKernelWrapper() ); } } JFunctionCapillaryPressure::KernelWrapper:: KernelWrapper( arrayView1d< TableFunction::KernelWrapper const > const & jFuncKernelWrappers, + arrayView1d< TableFunction::KernelWrapper const > const & inverseJFuncKernelWrappers, arrayView2d< real64 const > const & jFuncMultiplier, arrayView1d< integer const > const & phaseTypes, arrayView1d< integer const > const & phaseOrder, @@ -325,6 +373,7 @@ JFunctionCapillaryPressure::KernelWrapper:: phaseCapPres, dPhaseCapPres_dPhaseVolFrac ), m_jFuncKernelWrappers( jFuncKernelWrappers ), + m_inverseJFuncKernelWrappers( inverseJFuncKernelWrappers ), m_jFuncMultiplier( jFuncMultiplier ) {} @@ -333,6 +382,7 @@ JFunctionCapillaryPressure::createKernelWrapper() { createAllTableKernelWrappers(); return KernelWrapper( m_jFuncKernelWrappers, + m_inverseJFuncKernelWrappers, m_jFuncMultiplier, m_phaseTypes, m_phaseOrder, diff --git a/src/coreComponents/constitutive/capillaryPressure/JFunctionCapillaryPressure.hpp b/src/coreComponents/constitutive/capillaryPressure/JFunctionCapillaryPressure.hpp index 55f099e24fa..a7a27d14fcd 100644 --- a/src/coreComponents/constitutive/capillaryPressure/JFunctionCapillaryPressure.hpp +++ b/src/coreComponents/constitutive/capillaryPressure/JFunctionCapillaryPressure.hpp @@ -65,6 +65,7 @@ class JFunctionCapillaryPressure : public CapillaryPressureBase public: KernelWrapper( arrayView1d< TableFunction::KernelWrapper const > const & jFuncKernelWrappers, + arrayView1d< TableFunction::KernelWrapper const > const & inverseJFuncKernelWrappers, arrayView2d< real64 const > const & jFuncMultiplier, arrayView1d< integer const > const & phaseTypes, arrayView1d< integer const > const & phaseOrder, @@ -77,6 +78,13 @@ class JFunctionCapillaryPressure : public CapillaryPressureBase arraySlice1d< real64, cappres::USD_CAPPRES - 2 > const & phaseCapPres, arraySlice2d< real64, cappres::USD_CAPPRES_DS - 2 > const & dPhaseCapPres_dPhaseVolFrac ) const; + GEOS_HOST_DEVICE + void computeInv( arraySlice1d< real64, compflow::USD_PHASE - 1 > const & phaseVolFraction, + arraySlice1d< real64 const > const & jFuncMultiplier, + arraySlice1d< real64 const, cappres::USD_CAPPRES - 2 > const & phaseCapPres, + arraySlice2d< real64, cappres::USD_CAPPRES_DS - 2 > const & dPhaseCapPres_dPhaseVolFrac ) const; + + GEOS_HOST_DEVICE virtual void update( localIndex const k, localIndex const q, @@ -87,6 +95,7 @@ class JFunctionCapillaryPressure : public CapillaryPressureBase /// Array of kernel wrappers for the J-function /// Is of size 1 for two-phase flow, and of size 2 for three-phase flow arrayView1d< TableFunction::KernelWrapper const > const m_jFuncKernelWrappers; + arrayView1d< TableFunction::KernelWrapper const > const m_inverseJFuncKernelWrappers; /// Array of cell-wise J-function multipliers /// The second dimension is of size 1 for two-phase flow, and of size 2 for three-phase flow @@ -113,6 +122,7 @@ class JFunctionCapillaryPressure : public CapillaryPressureBase static constexpr char const * permeabilityExponentString() { return "permeabilityExponent"; } static constexpr char const * permeabilityDirectionString() { return "permeabilityDirection"; } static constexpr char const * jFunctionWrappersString() { return "jFunctionWrappers"; } + static constexpr char const * inverseJFunctionWrappersString() { return "inverseJFunctionWrappers"; } }; /** @@ -170,6 +180,9 @@ class JFunctionCapillaryPressure : public CapillaryPressureBase /// J-function kernel wrapper for the first pair (wetting-intermediate if NP=3, wetting-non-wetting otherwise) array1d< TableFunction::KernelWrapper > m_jFuncKernelWrappers; + array1d< TableFunction::KernelWrapper > m_inverseJFuncKernelWrappers; + + std::vector< std::shared_ptr > m_inverseTables; }; @@ -244,6 +257,41 @@ JFunctionCapillaryPressure::KernelWrapper:: } } +GEOS_HOST_DEVICE +inline void +JFunctionCapillaryPressure::KernelWrapper:: + computeInv( arraySlice1d< real64, compflow::USD_PHASE - 1 > const & phaseVolFraction, + arraySlice1d< real64 const > const & jFuncMultiplier, + arraySlice1d< real64 const, cappres::USD_CAPPRES - 2 > const & phaseCapPres, + arraySlice2d< real64, cappres::USD_CAPPRES_DS - 2 > const & dPhaseCapPres_dPhaseVolFrac ) const +{ + LvArray::forValuesInSlice( dPhaseCapPres_dPhaseVolFrac, []( real64 & val ){ val = 0.0; } ); + + using PT = CapillaryPressureBase::PhaseType; + integer const ipWater = m_phaseOrder[PT::WATER]; + integer const ipOil = m_phaseOrder[PT::OIL]; + integer const ipGas = m_phaseOrder[PT::GAS]; + + // apply multiplier + real64 capPresWater_J = phaseCapPres[ipWater] / jFuncMultiplier[0]; + // std::cout << GEOS_FMT( " JM_2 = ( {:4.2e} )", jFuncMultiplier[0] ); + array1d input(1); + input[0] = capPresWater_J; + // std::cout << GEOS_FMT( " J_int2 = ( {:4.2e} )", input[0] ); + // std::cout << GEOS_FMT( " Pc_int2 = ( {:4.2e} )", phaseCapPres[ipWater] ); + auto inputSlice = input.toSliceConst(); + + + + phaseVolFraction[ipWater] = + m_inverseJFuncKernelWrappers[0].compute( inputSlice, + &(dPhaseCapPres_dPhaseVolFrac)[ipWater][ipWater] ); + dPhaseCapPres_dPhaseVolFrac[ipWater][ipWater] /= jFuncMultiplier[0]; + // std::cout << GEOS_FMT( " S_int2 = ( {:4.2e} )", phaseVolFraction[ipWater] ); + // std::cout << GEOS_FMT( " dS/dP = ( {:4.2e} )", dPhaseCapPres_dPhaseVolFrac[ipWater][ipWater] ); + phaseVolFraction[ipGas] = 1.0 - phaseVolFraction[ipWater]; +} + GEOS_HOST_DEVICE inline void JFunctionCapillaryPressure::KernelWrapper:: diff --git a/src/coreComponents/constitutive/capillaryPressure/TableCapillaryPressure.hpp b/src/coreComponents/constitutive/capillaryPressure/TableCapillaryPressure.hpp index 739b9993083..602946c55de 100644 --- a/src/coreComponents/constitutive/capillaryPressure/TableCapillaryPressure.hpp +++ b/src/coreComponents/constitutive/capillaryPressure/TableCapillaryPressure.hpp @@ -65,6 +65,12 @@ class TableCapillaryPressure : public CapillaryPressureBase arraySlice1d< real64, cappres::USD_CAPPRES - 2 > const & phaseCapPres, arraySlice2d< real64, cappres::USD_CAPPRES_DS - 2 > const & dPhaseCapPres_dPhaseVolFrac ) const; + GEOS_HOST_DEVICE + void computeInv( arraySlice1d< real64, compflow::USD_PHASE - 1 > const & phaseVolFraction, + arraySlice1d< real64 const, cappres::USD_CAPPRES - 2 > const & phaseCapPres, + arraySlice2d< real64, cappres::USD_CAPPRES_DS - 2 > const & dPhaseCapPres_dPhaseVolFrac ) const; + + GEOS_HOST_DEVICE virtual void update( localIndex const k, localIndex const q, @@ -173,6 +179,28 @@ TableCapillaryPressure::KernelWrapper:: } } +GEOS_HOST_DEVICE +inline void +TableCapillaryPressure::KernelWrapper:: + computeInv( arraySlice1d< real64, compflow::USD_PHASE - 1 > const & phaseVolFraction, + arraySlice1d< real64 const, cappres::USD_CAPPRES - 2 > const & phaseCapPres, + arraySlice2d< real64, cappres::USD_CAPPRES_DS - 2 > const & dPhaseCapPres_dPhaseVolFrac ) const +{ + LvArray::forValuesInSlice( dPhaseCapPres_dPhaseVolFrac, []( real64 & val ){ val = 0.0; } ); + + using PT = CapillaryPressureBase::PhaseType; + integer const ipWater = m_phaseOrder[PT::WATER]; + // integer const ipOil = m_phaseOrder[PT::OIL]; + // integer const ipGas = m_phaseOrder[PT::GAS]; + + // put capillary pressure on the wetting phase + + phaseVolFraction[ipWater] = + m_capPresKernelWrappers[0].compute( &(phaseCapPres)[ipWater], + &(dPhaseCapPres_dPhaseVolFrac)[ipWater][ipWater] ); + +} + GEOS_HOST_DEVICE inline void TableCapillaryPressure::KernelWrapper:: diff --git a/src/coreComponents/constitutive/capillaryPressure/capillaryPressureSelector.hpp b/src/coreComponents/constitutive/capillaryPressure/capillaryPressureSelector.hpp index b164f55aa16..90c362850b6 100644 --- a/src/coreComponents/constitutive/capillaryPressure/capillaryPressureSelector.hpp +++ b/src/coreComponents/constitutive/capillaryPressure/capillaryPressureSelector.hpp @@ -36,20 +36,24 @@ template< typename LAMBDA > void constitutiveUpdatePassThru( CapillaryPressureBase const & capPres, LAMBDA && lambda ) { - ConstitutivePassThruHandler< BrooksCoreyCapillaryPressure, + ConstitutivePassThruHandler< + BrooksCoreyCapillaryPressure, JFunctionCapillaryPressure, TableCapillaryPressure, - VanGenuchtenCapillaryPressure >::execute( capPres, std::forward< LAMBDA >( lambda ) ); + VanGenuchtenCapillaryPressure + >::execute( capPres, std::forward< LAMBDA >( lambda ) ); } template< typename LAMBDA > void constitutiveUpdatePassThru( CapillaryPressureBase & capPres, LAMBDA && lambda ) { - ConstitutivePassThruHandler< BrooksCoreyCapillaryPressure, + ConstitutivePassThruHandler< + BrooksCoreyCapillaryPressure, JFunctionCapillaryPressure, TableCapillaryPressure, - VanGenuchtenCapillaryPressure >::execute( capPres, std::forward< LAMBDA >( lambda ) ); + VanGenuchtenCapillaryPressure + >::execute( capPres, std::forward< LAMBDA >( lambda ) ); } } // namespace constitutive diff --git a/src/coreComponents/finiteVolume/CellElementStencilTPFA.hpp b/src/coreComponents/finiteVolume/CellElementStencilTPFA.hpp index 88fa3bb2b27..391d614baba 100644 --- a/src/coreComponents/finiteVolume/CellElementStencilTPFA.hpp +++ b/src/coreComponents/finiteVolume/CellElementStencilTPFA.hpp @@ -70,6 +70,20 @@ class CellElementStencilTPFAWrapper : public StencilWrapperBase< TwoPointStencil CoefficientAccessor< arrayView3d< real64 const > > const & dCoeff_dVar, real64 ( &weight )[1][2], real64 ( &dWeight_dVar )[1][2] ) const; +/** + * @brief Compute half weights and derivatives w.r.t to one variable. + * @param[in] iconn connection index + * @param[in] coefficient view accessor to the coefficient used to compute the weights + * @param[in] dCoeff_dVar view accessor to the derivative of the coefficient w.r.t to the variable + * @param[out] weight view weights + * @param[out] dWeight_dVar derivative of the weights w.r.t to the variable + */ + GEOS_HOST_DEVICE + void computeHalfWeights( localIndex const iconn, + CoefficientAccessor< arrayView3d< real64 const > > const & coefficient, + CoefficientAccessor< arrayView3d< real64 const > > const & dCoeff_dVar, + real64 ( &weight )[1][2], + real64 ( &dWeight_dVar )[1][2] ) const; /** * @brief Compute weights and derivatives w.r.t to one variable without coefficient @@ -293,6 +307,90 @@ CellElementStencilTPFAWrapper:: } } +GEOS_HOST_DEVICE +inline void +CellElementStencilTPFAWrapper:: + computeHalfWeights( localIndex const iconn, + CoefficientAccessor< arrayView3d< real64 const > > const & coefficient, + CoefficientAccessor< arrayView3d< real64 const > > const & dCoeff_dVar, + real64 (& weight)[1][2], + real64 (& dWeight_dVar )[1][2] ) const +{ + real64 halfWeight[2]; + real64 dHalfWeight_dVar[2]; + + // real64 const tolerance = 1e-30 * lengthTolerance; // TODO: choice of constant based on physics? + + for( localIndex i = 0; i < 2; ++i ) + { + localIndex const er = m_elementRegionIndices[iconn][i]; + localIndex const esr = m_elementSubRegionIndices[iconn][i]; + localIndex const ei = m_elementIndices[iconn][i]; + + halfWeight[i] = m_weights[iconn][i]; + dHalfWeight_dVar[i] = m_weights[iconn][i]; + + // Proper computation + real64 faceNormal[3]; + LvArray::tensorOps::copy< 3 >( faceNormal, m_faceNormal[iconn] ); + if( LvArray::tensorOps::AiBi< 3 >( m_cellToFaceVec[iconn][i], faceNormal ) < 0.0 ) + { + LvArray::tensorOps::scale< 3 >( faceNormal, -1 ); + } + + real64 faceConormal[3]; + real64 dFaceConormal_dVar[3]; + LvArray::tensorOps::hadamardProduct< 3 >( faceConormal, coefficient[er][esr][ei][0], faceNormal ); + LvArray::tensorOps::hadamardProduct< 3 >( dFaceConormal_dVar, dCoeff_dVar[er][esr][ei][0], faceNormal ); + halfWeight[i] *= LvArray::tensorOps::AiBi< 3 >( m_cellToFaceVec[iconn][i], faceConormal ); + dHalfWeight_dVar[i] *= LvArray::tensorOps::AiBi< 3 >( m_cellToFaceVec[iconn][i], dFaceConormal_dVar ); + + // correct negative weight issue arising from non-K-orthogonal grids + // if( halfWeight[i] < 0.0 ) + // { + // LvArray::tensorOps::hadamardProduct< 3 >( faceConormal, + // coefficient[er][esr][ei][0], + // m_cellToFaceVec[iconn][i] ); + // LvArray::tensorOps::hadamardProduct< 3 >( dFaceConormal_dVar, + // dCoeff_dVar[er][esr][ei][0], + // m_cellToFaceVec[iconn][i] ); + // halfWeight[i] = m_weights[iconn][i]; + // dHalfWeight_dVar[i] = m_weights[iconn][i]; + // halfWeight[i] *= LvArray::tensorOps::AiBi< 3 >( m_cellToFaceVec[iconn][i], faceConormal ); + // dHalfWeight_dVar[i] *= LvArray::tensorOps::AiBi< 3 >( m_cellToFaceVec[iconn][i], dFaceConormal_dVar ); + // } + } + + // // Do harmonic and arithmetic averaging + // real64 const product = halfWeight[0]*halfWeight[1]; + // real64 const sum = halfWeight[0]+halfWeight[1]; + + // real64 const harmonicWeight = sum > 0 ? product / sum : 0.0; + // real64 const arithmeticWeight = sum / 2; + + // real64 dHarmonicWeight_dVar[2]; + // real64 dArithmeticWeight_dVar[2]; + + // dHarmonicWeight_dVar[0] = sum > 0 ? (dHalfWeight_dVar[0]*sum*halfWeight[1] - dHalfWeight_dVar[0]*halfWeight[0]*halfWeight[1]) / ( sum*sum ) : 0.0; + // dHarmonicWeight_dVar[1] = sum > 0 ? (dHalfWeight_dVar[1]*sum*halfWeight[0] - dHalfWeight_dVar[1]*halfWeight[1]*halfWeight[0]) / ( sum*sum ) : 0.0; + + // dArithmeticWeight_dVar[0] = dHalfWeight_dVar[0] / 2; + // dArithmeticWeight_dVar[1] = dHalfWeight_dVar[1] / 2; + + // real64 const meanPermCoeff = 1.0; //TODO make it a member if it is really necessary + + // real64 const value = meanPermCoeff * harmonicWeight + (1 - meanPermCoeff) * arithmeticWeight; + for( localIndex ke = 0; ke < 2; ++ke ) + { + // weight[0][ke] = m_transMultiplier[iconn] * value * (ke == 0 ? 1 : -1); + weight[0][ke] = m_transMultiplier[iconn] * halfWeight[ke] * (ke == 0 ? 1 : -1); + + // real64 const dValue_dVar = meanPermCoeff * dHarmonicWeight_dVar[ke] + (1 - meanPermCoeff) * dArithmeticWeight_dVar[ke]; + // dWeight_dVar[0][ke] = m_transMultiplier[iconn] * dValue_dVar; + dWeight_dVar[0][ke] = m_transMultiplier[iconn] * dHalfWeight_dVar[ke]; + } +} + GEOS_HOST_DEVICE inline void CellElementStencilTPFAWrapper:: diff --git a/src/coreComponents/finiteVolume/EmbeddedSurfaceToCellStencil.hpp b/src/coreComponents/finiteVolume/EmbeddedSurfaceToCellStencil.hpp index 7f9c1562366..27462c5b516 100644 --- a/src/coreComponents/finiteVolume/EmbeddedSurfaceToCellStencil.hpp +++ b/src/coreComponents/finiteVolume/EmbeddedSurfaceToCellStencil.hpp @@ -98,6 +98,22 @@ class EmbeddedSurfaceToCellStencilWrapper : public StencilWrapperBase< TwoPointS real64 ( &weight )[1][2], real64 ( &dWeight_dVar )[1][2] ) const; + /** + * @brief Compute half weigths and derivatives w.r.t to one variable. + * @param[in] iconn connection index + * @param[in] coefficient view accessor to the coefficient used to compute the weights + * @param[in] dCoeff_dVar view accessor to the derivative of the coefficient w.r.t to the variable + * @param[out] weight view weights + * @param[out] dWeight_dVar derivative of the weigths w.r.t to the variable + */ + + GEOS_HOST_DEVICE + void computeHalfWeights( localIndex const iconn, + CoefficientAccessor< arrayView3d< real64 const > > const & coefficient, + CoefficientAccessor< arrayView3d< real64 const > > const & dCoeff_dVar, + real64 ( &weight )[1][2], + real64 ( &dWeight_dVar )[1][2] ) const; + /** * @brief Compute weigths and derivatives w.r.t to one variable without coefficient * Used in ReactiveCompositionalMultiphaseOBL solver for thermal transmissibility computation: @@ -243,6 +259,42 @@ EmbeddedSurfaceToCellStencilWrapper:: dWeight_dVar[0][1] = ( t0 * dt1 * sumOfTrans - dt1 * t0 * t1 ) / ( sumOfTrans * sumOfTrans ); } +GEOS_HOST_DEVICE +inline void +EmbeddedSurfaceToCellStencilWrapper:: + computeHalfWeights( localIndex iconn, + CoefficientAccessor< arrayView3d< real64 const > > const & coefficient, + CoefficientAccessor< arrayView3d< real64 const > > const & dCoeff_dVar, + real64 ( & weight )[1][2], + real64 ( & dWeight_dVar )[1][2] ) const +{ + localIndex const er0 = m_elementRegionIndices[iconn][0]; + localIndex const esr0 = m_elementSubRegionIndices[iconn][0]; + localIndex const ei0 = m_elementIndices[iconn][0]; + + localIndex const er1 = m_elementRegionIndices[iconn][1]; + localIndex const esr1 = m_elementSubRegionIndices[iconn][1]; + localIndex const ei1 = m_elementIndices[iconn][1]; + + // Will change when implementing collocation points. Will use fracture normal to project the permeability + real64 const t0 = m_weights[iconn][0] * LvArray::tensorOps::l2Norm< 3 >( coefficient[er0][esr0][ei0][0] ); + // We consider the 3rd component of the permeability which is the normal one. + real64 const t1 = m_weights[iconn][1] * coefficient[er1][esr1][ei1][0][2]; + + real64 const sumOfTrans = t0+t1; + real64 const value = t0*t1/sumOfTrans; + + weight[0][0] = value; + weight[0][1] = -value; + + // We consider the 3rd component of the permeability which is the normal one. + real64 const dt0 = m_weights[iconn][0] * dCoeff_dVar[er0][esr0][ei0][0][0]; + real64 const dt1 = m_weights[iconn][1] * dCoeff_dVar[er1][esr1][ei1][0][2]; + + dWeight_dVar[0][0] = ( dt0 * t1 * sumOfTrans - dt0 * t0 * t1 ) / ( sumOfTrans * sumOfTrans ); + dWeight_dVar[0][1] = ( t0 * dt1 * sumOfTrans - dt1 * t0 * t1 ) / ( sumOfTrans * sumOfTrans ); +} + GEOS_HOST_DEVICE inline void EmbeddedSurfaceToCellStencilWrapper:: diff --git a/src/coreComponents/finiteVolume/FaceElementToCellStencil.hpp b/src/coreComponents/finiteVolume/FaceElementToCellStencil.hpp index 3b970bd8b2b..a01a4541e85 100644 --- a/src/coreComponents/finiteVolume/FaceElementToCellStencil.hpp +++ b/src/coreComponents/finiteVolume/FaceElementToCellStencil.hpp @@ -106,6 +106,21 @@ class FaceElementToCellStencilWrapper : public StencilWrapperBase< TwoPointStenc real64 ( &weight )[1][2], real64 ( &dWeight_dVar )[1][2] ) const; +/** + * @brief Compute half weigths and derivatives w.r.t to one variable. + * @param[in] iconn connection index + * @param[in] coefficient view accessor to the coefficient used to compute the weights + * @param[in] dCoeff_dVar view accessor to the derivative of the coefficient w.r.t to the variable + * @param[out] weight view weights + * @param[out] dWeight_dVar derivative of the weigths w.r.t to the variable + */ + GEOS_HOST_DEVICE + void computeHalfWeights( localIndex iconn, + CoefficientAccessor< arrayView3d< real64 const > > const & coefficient, + CoefficientAccessor< arrayView3d< real64 const > > const & dCoeff_dVar, + real64 ( &weight )[1][2], + real64 ( &dWeight_dVar )[1][2] ) const; + /** * @brief Compute weigths and derivatives w.r.t to one variable without coefficient * Used in ReactiveCompositionalMultiphaseOBL solver for thermal transmissibility computation: @@ -289,6 +304,44 @@ inline void FaceElementToCellStencilWrapper:: dWeight_dVar[0][1] = ( t0 * dt1 * sumOfTrans - dt1 * t0 * t1 ) / ( sumOfTrans * sumOfTrans ); } +GEOS_HOST_DEVICE +inline void FaceElementToCellStencilWrapper:: + computeHalfWeights( localIndex const iconn, + CoefficientAccessor< arrayView3d< real64 const > > const & coefficient, + CoefficientAccessor< arrayView3d< real64 const > > const & dCoeff_dVar, + real64 ( & weight )[1][2], + real64 ( & dWeight_dVar )[1][2] ) const +{ + localIndex const er0 = m_elementRegionIndices[iconn][0]; + localIndex const esr0 = m_elementSubRegionIndices[iconn][0]; + localIndex const ei0 = m_elementIndices[iconn][0]; + + localIndex const er1 = m_elementRegionIndices[iconn][1]; + localIndex const esr1 = m_elementSubRegionIndices[iconn][1]; + localIndex const ei1 = m_elementIndices[iconn][1]; + + real64 faceConormal[3]; + + // Will change when implementing collocation points. + LvArray::tensorOps::hadamardProduct< 3 >( faceConormal, coefficient[er0][esr0][ei0][0], m_faceNormal[iconn] ); + real64 const t0 = m_weights[iconn][0] * LvArray::tensorOps::AiBi< 3 >( m_cellToFaceVec[iconn], faceConormal ); + // We consider the 3rd component of the permeability which is the normal one. + real64 const t1 = m_weights[iconn][1] * coefficient[er1][esr1][ei1][0][2]; + + real64 const sumOfTrans = t0+t1; + real64 const value = m_transMultiplier[iconn]*t0*t1/sumOfTrans; + + weight[0][0] = value; + weight[0][1] = -value; + + // We consider the 3rd component of the permeability which is the normal one. + real64 const dt0 = m_weights[iconn][0] * dCoeff_dVar[er0][esr0][ei0][0][0]; + real64 const dt1 = m_weights[iconn][1] * dCoeff_dVar[er1][esr1][ei1][0][2]; + + dWeight_dVar[0][0] = ( dt0 * t1 * sumOfTrans - dt0 * t0 * t1 ) / ( sumOfTrans * sumOfTrans ); + dWeight_dVar[0][1] = ( t0 * dt1 * sumOfTrans - dt1 * t0 * t1 ) / ( sumOfTrans * sumOfTrans ); +} + GEOS_HOST_DEVICE inline void FaceElementToCellStencilWrapper diff --git a/src/coreComponents/finiteVolume/SurfaceElementStencil.hpp b/src/coreComponents/finiteVolume/SurfaceElementStencil.hpp index 69b2a85c08a..a6492187386 100644 --- a/src/coreComponents/finiteVolume/SurfaceElementStencil.hpp +++ b/src/coreComponents/finiteVolume/SurfaceElementStencil.hpp @@ -110,6 +110,21 @@ class SurfaceElementStencilWrapper : public StencilWrapperBase< SurfaceElementSt real64 ( &weight )[maxNumConnections][2], real64 ( &dWeight_dVar )[maxNumConnections][2] ) const; + /** + * @brief Compute weights and derivatives w.r.t to one variable. + * @param[in] iconn connection index + * @param[in] coefficient view accessor to the coefficient used to compute the weights + * @param[in] dCoeff_dVar view accessor to the derivative of the coefficient w.r.t to the variable + * @param[out] weight view weights + * @param[out] dWeight_dVar derivative of the weights w.r.t to the variable + */ + GEOS_HOST_DEVICE + void computeHalfWeights( localIndex iconn, + CoefficientAccessor< arrayView3d< real64 const > > const & coefficient, + CoefficientAccessor< arrayView3d< real64 const > > const & dCoeff_dVar, + real64 ( &weight )[maxNumConnections][2], + real64 ( &dWeight_dVar )[maxNumConnections][2] ) const; + /** * @brief Compute weights and derivatives w.r.t to one variable without coefficient * Used in ReactiveCompositionalMultiphaseOBL solver for thermal transmissibility computation: @@ -364,6 +379,70 @@ SurfaceElementStencilWrapper:: } } +GEOS_HOST_DEVICE +inline void +SurfaceElementStencilWrapper:: + computeHalfWeights( localIndex iconn, + CoefficientAccessor< arrayView3d< real64 const > > const & coefficient, + CoefficientAccessor< arrayView3d< real64 const > > const & dCoeff_dVar, + real64 ( & weight )[maxNumConnections][2], + real64 ( & dWeight_dVar )[maxNumConnections][2] ) const +{ + + real64 sumOfTrans = 0.0; + for( localIndex k=0; k >( dataGroup.size(), capPresWrapper, @@ -622,13 +624,17 @@ void ImmiscibleMultiphaseFlow::assembleFluxTerms( real64 const dt, { mesh.getElemManager().forElementSubRegions( regionNames, [&]( localIndex const, - ElementSubRegionBase & subRegion ) - { + ElementSubRegionBase & subRegion ) // Check if you need this. + { + // Capillary pressure wrapper string const & cappresName = subRegion.getReference< string >( viewKeyStruct::capPressureNamesString() ); - CapillaryPressureBase & capPressure = getConstitutiveModel< CapillaryPressureBase >( subRegion, cappresName ); - constitutive::constitutiveUpdatePassThru( capPressure, [&] ( auto & castedCapPres ) - { - typename TYPEOFREF( castedCapPres ) ::KernelWrapper capPresWrapper = castedCapPres.createKernelWrapper(); + JFunctionCapillaryPressure & capPressure = getConstitutiveModel< JFunctionCapillaryPressure >( subRegion, cappresName ); + JFunctionCapillaryPressure::KernelWrapper capPresWrapper = capPressure.createKernelWrapper(); + + // Relative permeability wrapper + string const & relPermName = subRegion.getReference< string >( viewKeyStruct::relPermNamesString() ); + BrooksCoreyRelativePermeability & relPerm = getConstitutiveModel< BrooksCoreyRelativePermeability >( subRegion, relPermName ); + BrooksCoreyRelativePermeability::KernelWrapper relPermWrapper = relPerm.createKernelWrapper(); fluxApprox.forAllStencils( mesh, [&]( auto & stencil ) { @@ -644,12 +650,13 @@ void ImmiscibleMultiphaseFlow::assembleFluxTerms( real64 const dt, mesh.getElemManager(), stencilWrapper, capPresWrapper, + relPermWrapper, + subRegion, dt, localMatrix.toViewConstSizes(), localRhs.toView() ); } ); } ); - } ); } else { diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/CapillaryPressureUpdateKernel.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/CapillaryPressureUpdateKernel.hpp new file mode 100644 index 00000000000..2a02f536ea9 --- /dev/null +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/CapillaryPressureUpdateKernel.hpp @@ -0,0 +1,73 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * SPDX-License-Identifier: LGPL-2.1-only + * + * Copyright (c) 2016-2024 Lawrence Livermore National Security LLC + * Copyright (c) 2018-2024 TotalEnergies + * Copyright (c) 2018-2024 The Board of Trustees of the Leland Stanford Junior University + * Copyright (c) 2023-2024 Chevron + * Copyright (c) 2019- GEOS/GEOSX Contributors + * All rights reserved + * + * See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details. + * ------------------------------------------------------------------------------------------------------------ + */ + +/** + * @file CapillaryPressureUpdateKernel.hpp + */ + +#ifndef GEOS_PHYSICSSOLVERS_FLUIDFLOW_IMMISCIBLEMULTIPHASE_CAPILLARYPRESSUREUPDATEKERNEL_HPP +#define GEOS_PHYSICSSOLVERS_FLUIDFLOW_IMMISCIBLEMULTIPHASE_CAPILLARYPRESSUREUPDATEKERNEL_HPP + +#include "common/DataTypes.hpp" +#include "common/GEOS_RAJA_Interface.hpp" + +namespace geos +{ + +namespace immiscibleMultiphaseKernels +{ + +/******************************** CapillaryPressureUpdateKernel ********************************/ + +struct CapillaryPressureUpdateKernel +{ + template< typename POLICY, typename CAPPRES_WRAPPER > + static void + launch( localIndex const size, + CAPPRES_WRAPPER const & capPresWrapper, + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const & phaseVolFrac ) + { + forAll< POLICY >( size, [=] GEOS_HOST_DEVICE ( localIndex const k ) + { + for( localIndex q = 0; q < capPresWrapper.numGauss(); ++q ) + { + capPresWrapper.update( k, q, phaseVolFrac[k] ); + } + } ); + } + + template< typename POLICY, typename CAPPRES_WRAPPER > + static void + launch( SortedArrayView< localIndex const > const & targetSet, + CAPPRES_WRAPPER const & capPresWrapper, + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const & phaseVolFrac ) + { + forAll< POLICY >( targetSet.size(), [=] GEOS_HOST_DEVICE ( localIndex const a ) + { + localIndex const k = targetSet[a]; + for( localIndex q = 0; q < capPresWrapper.numGauss(); ++q ) + { + capPresWrapper.update( k, q, phaseVolFrac[k] ); + } + } ); + } +}; + +} // namespace immiscibleMultiphaseKernels + +} // namespace geos + + +#endif //GEOS_PHYSICSSOLVERS_FLUIDFLOW_IMMISCIBLEMULTIPHASE_CAPILLARYPRESSUREUPDATEKERNEL_HPP diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp index ef3b45ce09b..fa6b6f69d17 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp @@ -32,12 +32,15 @@ #include "constitutive/fluid/twophasefluid/TwoPhaseFluidFields.hpp" #include "constitutive/capillaryPressure/CapillaryPressureFields.hpp" #include "constitutive/capillaryPressure/CapillaryPressureBase.hpp" +#include "constitutive/capillaryPressure/JFunctionCapillaryPressure.hpp" +#include "constitutive/capillaryPressure/TableCapillaryPressure.hpp" #include "constitutive/permeability/PermeabilityBase.hpp" #include "constitutive/permeability/PermeabilityFields.hpp" #include "constitutive/relativePermeability/RelativePermeabilityBase.hpp" #include "constitutive/relativePermeability/RelativePermeabilityFields.hpp" #include "fieldSpecification/AquiferBoundaryCondition.hpp" #include "finiteVolume/BoundaryStencil.hpp" +#include "finiteVolume/CellElementStencilTPFA.hpp" #include "finiteVolume/FluxApproximationBase.hpp" #include "linearAlgebra/interfaces/InterfaceTypes.hpp" #include "physicsSolvers/fluidFlow/FlowSolverBaseFields.hpp" @@ -103,12 +106,15 @@ class FaceBasedAssemblyKernelBase using MultiphaseFluidAccessors = StencilMaterialAccessors< constitutive::TwoPhaseFluid, fields::twophasefluid::phaseDensity, - fields::twophasefluid::dPhaseDensity >; + fields::twophasefluid::dPhaseDensity, + fields::twophasefluid::phaseViscosity, + fields::twophasefluid::dPhaseViscosity >; using CapPressureAccessors = - StencilMaterialAccessors< CapillaryPressureBase, + StencilMaterialAccessors< JFunctionCapillaryPressure, fields::cappres::phaseCapPressure, - fields::cappres::dPhaseCapPressure_dPhaseVolFraction >; + fields::cappres::dPhaseCapPressure_dPhaseVolFraction, + fields::cappres::jFuncMultiplier >; using PermeabilityAccessors = StencilMaterialAccessors< PermeabilityBase, @@ -158,9 +164,12 @@ class FaceBasedAssemblyKernelBase m_mob( multiPhaseFlowAccessors.get( fields::immiscibleMultiphaseFlow::phaseMobility {} ) ), m_dMob( multiPhaseFlowAccessors.get( fields::immiscibleMultiphaseFlow::dPhaseMobility {} ) ), m_dens( fluidAccessors.get( fields::twophasefluid::phaseDensity {} ) ), + m_visc( fluidAccessors.get( fields::twophasefluid::phaseViscosity {} ) ), m_dDens_dPres( fluidAccessors.get( fields::twophasefluid::dPhaseDensity {} ) ), + m_dVisc_dPres( fluidAccessors.get( fields::twophasefluid::dPhaseViscosity {} ) ), m_phaseCapPressure( capPressureAccessors.get( fields::cappres::phaseCapPressure {} ) ), m_dPhaseCapPressure_dPhaseVolFrac( capPressureAccessors.get( fields::cappres::dPhaseCapPressure_dPhaseVolFraction {} ) ), + m_jFuncMultiplier( capPressureAccessors.get( fields::cappres::jFuncMultiplier {} ) ), m_localMatrix( localMatrix ), m_localRhs( localRhs ), m_hasCapPressure ( hasCapPressure ), @@ -199,16 +208,20 @@ class FaceBasedAssemblyKernelBase ElementViewConst< arrayView2d< real64 const, immiscibleFlow::USD_PHASE > > const m_mob; ElementViewConst< arrayView3d< real64 const, immiscibleFlow::USD_PHASE_DS > > const m_dMob; - /// Views on fluid density + /// Views on fluid density and viscosity ElementViewConst< arrayView3d< real64 const, constitutive::multifluid::USD_PHASE > > const m_dens; + ElementViewConst< arrayView3d< real64 const, constitutive::multifluid::USD_PHASE > > const m_visc; ElementViewConst< arrayView4d< real64 const, constitutive::multifluid::USD_PHASE_DC > > const m_dDens_dPres; + ElementViewConst< arrayView4d< real64 const, constitutive::multifluid::USD_PHASE_DC > > const m_dVisc_dPres; /// Views on capillary pressure ElementViewConst< arrayView3d< real64 const, cappres::USD_CAPPRES > > const m_phaseCapPressure; ElementViewConst< arrayView4d< real64 const, cappres::USD_CAPPRES_DS > > const m_dPhaseCapPressure_dPhaseVolFrac; + ElementViewConst< arrayView2d< real64 const > > const m_jFuncMultiplier; // Residual and jacobian + /// View on the local CRS matrix CRSMatrixView< real64, globalIndex const > const m_localMatrix; /// View on the local RHS @@ -334,6 +347,11 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase /// Derivatives of transmissibility with respect to pressure real64 dTrans_dPres[maxNumConns][2]{}; + /// Transmissibility + real64 transmissibilityHat[maxNumConns][2]{}; + /// Derivatives of transmissibility with respect to pressure + real64 dTransHat_dPres[maxNumConns][2]{}; + // Local degrees of freedom and local residual/jacobian /// Indices of the matrix rows/columns corresponding to the dofs in this face @@ -751,14 +769,16 @@ class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase typename STENCILWRAPPER::IndexContainerViewConstType const m_sei; }; + /** * @class FaceBasedAssemblyInterfaceConditionKernel * @tparam NUM_DOF number of degrees of freedom * @tparam STENCILWRAPPER the type of the stencil wrapper * @tparam CAPPRESWRAPPER the type of the capillary pressure wrapper + * @tparam RELPERMWRAPPER the type of the realtive permeability wrapper * @brief Define the interface for the assembly kernel in charge of flux terms */ -template< integer NUM_EQN, integer NUM_DOF, typename STENCILWRAPPER, typename CAPPRESWRAPPER > +template< integer NUM_EQN, integer NUM_DOF, typename STENCILWRAPPER, typename CAPPRESWRAPPER, typename RELPERMWRAPPER > class FaceBasedAssemblyInterfaceConditionKernel : public FaceBasedAssemblyKernel< NUM_EQN, NUM_DOF, STENCILWRAPPER > { public: @@ -785,9 +805,12 @@ class FaceBasedAssemblyInterfaceConditionKernel : public FaceBasedAssemblyKernel using Base::m_dPerm_dPres; using Base::m_phaseVolFrac; using Base::m_phaseCapPressure; + using Base::m_jFuncMultiplier; using Base::m_dPhaseCapPressure_dPhaseVolFrac; using Base::m_dens; using Base::m_dDens_dPres; + using Base::m_visc; + using Base::m_dVisc_dPres; using Base::m_dMob; using Base::m_mob; using Base::m_gravCoef; @@ -822,6 +845,7 @@ class FaceBasedAssemblyInterfaceConditionKernel : public FaceBasedAssemblyKernel globalIndex const rankOffset, STENCILWRAPPER const & stencilWrapper, CAPPRESWRAPPER const & capPressureWrapper, + RELPERMWRAPPER const & relPermWrapper, DofNumberAccessor const & dofNumberAccessor, ImmiscibleMultiphaseFlowAccessors const & multiPhaseFlowAccessors, MultiphaseFluidAccessors const & fluidAccessors, @@ -832,7 +856,8 @@ class FaceBasedAssemblyInterfaceConditionKernel : public FaceBasedAssemblyKernel arrayView1d< real64 > const & localRhs, integer const hasCapPressure, integer const useTotalMassEquation, - integer const checkPhasePresenceInGravity ) + integer const checkPhasePresenceInGravity, + localIndex const GEOS_UNUSED_PARAM(domainSize) ) : Base( numPhases, rankOffset, stencilWrapper, @@ -847,7 +872,8 @@ class FaceBasedAssemblyInterfaceConditionKernel : public FaceBasedAssemblyKernel hasCapPressure, useTotalMassEquation, checkPhasePresenceInGravity ), - m_capPressureWrapper( capPressureWrapper ) + m_capPressureWrapper( capPressureWrapper ), + m_relPermWrapper( relPermWrapper ) {} /** @@ -857,6 +883,7 @@ class FaceBasedAssemblyInterfaceConditionKernel : public FaceBasedAssemblyKernel * @param[inout] stack the stack variables * @param[in] NoOpFunc the function used to customize the computation of the flux */ + template< typename FUNC = NoOpFunc > // should change to multiphase GEOS_HOST_DEVICE void computeFlux( localIndex const iconn, @@ -874,6 +901,12 @@ class FaceBasedAssemblyInterfaceConditionKernel : public FaceBasedAssemblyKernel localIndex k[2]; localIndex connectionIndex = 0; + m_stencilWrapper.computeHalfWeights( iconn, + m_permeability, + m_dPerm_dPres, + stack.transmissibilityHat, + stack.dTransHat_dPres ); + for( k[0] = 0; k[0] < stack.numFluxElems; ++k[0] ) { for( k[1] = k[0] + 1; k[1] < stack.numFluxElems; ++k[1] ) @@ -890,6 +923,7 @@ class FaceBasedAssemblyInterfaceConditionKernel : public FaceBasedAssemblyKernel real64 capGrad[numEqn]{}; real64 capPresIC[numEqn][2]{}; + real64 jFMultiplier[numEqn][2]{}; real64 dCapGrad_dP[numEqn][2]{}; real64 dCapGrad_dS[numEqn][2]{}; @@ -903,14 +937,22 @@ class FaceBasedAssemblyInterfaceConditionKernel : public FaceBasedAssemblyKernel real64 density2[numEqn]{}; real64 dDens_dP2[numEqn][2]{}; + real64 gravCoefHat[numEqn]{}; real64 uT = 0; + real64 total_mobility = 0; real64 duT_dP[numEqn]{}; real64 duT_dS[numEqn]{}; + real64 potGrad_ip[numEqn]{}; + real64 alpha_ip[numEqn]{}; + real64 const trans[2] = { stack.transmissibility[connectionIndex][0], stack.transmissibility[connectionIndex][1] }; real64 const dTrans_dP[2] = { stack.dTrans_dPres[connectionIndex][0], stack.dTrans_dPres[connectionIndex][1] }; + real64 const transHat[2] = { stack.transmissibilityHat[connectionIndex][0], stack.transmissibilityHat[connectionIndex][1] }; + real64 const dTransHat_dP[2] = { stack.dTransHat_dPres[connectionIndex][0], stack.dTransHat_dPres[connectionIndex][1] }; + // cell indices localIndex const seri[2] = {m_seri( iconn, k[0] ), m_seri( iconn, k[1] )}; localIndex const sesri[2] = {m_sesri( iconn, k[0] ), m_sesri( iconn, k[1] )}; @@ -956,6 +998,8 @@ class FaceBasedAssemblyInterfaceConditionKernel : public FaceBasedAssemblyKernel real64 dPresGrad_dTrans = 0.0; real64 dGravHead_dTrans = 0.0; real64 dCapGrad_dTrans = 0.0; + gravCoefHat[0] = 0; + gravCoefHat[1] = 0; constexpr int signPotDiff[2] = {1, -1}; for( integer ke = 0; ke < 2; ++ke ) @@ -971,6 +1015,8 @@ class FaceBasedAssemblyInterfaceConditionKernel : public FaceBasedAssemblyKernel real64 const gravD = trans[ke] * m_gravCoef[er][esr][ei]; // D = T g z1 || -T g z2 real64 pot = trans[ke] * pressure - densMean[ip] * gravD; // Phi = T P1 - rho T g z1 || -T P2 + rho T g z2 + gravCoefHat[0] += m_gravCoef[er][esr][ei] * 0.5; + gravCoefHat[1] += m_gravCoef[er][esr][ei] * 0.5; gravHead[ip] += densMean[ip] * gravD; // DPg = rho (T g z1 - T g z2) = T rho g (z1 - z2) dGravHead_dTrans += signPotDiff[ke] * densMean[ip] * m_gravCoef[er][esr][ei]; // dDPg/dT = rho g z1 - rho g z2 = rho g (z1 - z2) @@ -983,6 +1029,8 @@ class FaceBasedAssemblyInterfaceConditionKernel : public FaceBasedAssemblyKernel if( m_hasCapPressure ) // check sign convention { real64 const capPres = m_phaseCapPressure[er][esr][ei][0][ip]; // Pc = Pc1 || Pc2 + jFMultiplier[ip][ke] = m_jFuncMultiplier[er][esr][ei][0]; + capPresIC[ip][ke] = capPres; dCapGrad_dTrans -= signPotDiff[ke] * capPres; // dDPc/dT = (-Pc1 + Pc2) pot -= trans[ke] * capPres; // Phi = T P1 - rho T g z1 - T Pc1 || -T P2 + rho T g z2 + T @@ -993,6 +1041,11 @@ class FaceBasedAssemblyInterfaceConditionKernel : public FaceBasedAssemblyKernel potScale = fmax( potScale, fabs( pot ) ); // maxPhi = Phi1 > Phi2 ? Phi1 : Phi2 } + // std::cout << GEOS_FMT( " z1 = ( {:4.2e} )", m_gravCoef[seri[0]][sesri[0]][sei[0]] ); + // std::cout << GEOS_FMT( " z2 = ( {:4.2e} )", m_gravCoef[seri[1]][sesri[1]][sei[1]] ); + // std::cout << GEOS_FMT( " zhat1 = ( {:4.2e} )", gravCoefHat[0] ); + // std::cout << GEOS_FMT( " zhat2 = ( {:4.2e} )", gravCoefHat[1] ); + for( integer ke = 0; ke < 2; ++ke ) { dPresGrad_dP[ip][ke] += dTrans_dP[ke] * dPresGrad_dTrans; // dDPv/dP = { T + dT/dP1 * (P1 - P2) , -T + dT/dP2 * (P1 - P2)} @@ -1027,7 +1080,7 @@ class FaceBasedAssemblyInterfaceConditionKernel : public FaceBasedAssemblyKernel // maxPhi * tol : eps // decide mobility coefficients - smooth variation in [-upwAbsTol; upwAbsTol] - real64 const alpha = ( potGrad + upwAbsTol ) / ( 2 * upwAbsTol ); // alpha = (DPhi + abstol) / abstol / 2 + real64 alpha = ( potGrad + upwAbsTol ) / ( 2 * upwAbsTol ); // alpha = (DPhi + abstol) / abstol / 2 // choose upstream cell if( alpha <= 0.0 || alpha >= 1.0 ) // no smoothing needed @@ -1123,7 +1176,13 @@ class FaceBasedAssemblyInterfaceConditionKernel : public FaceBasedAssemblyKernel duT_dS[ke] += dFlux_dS[ip][ke] / density2[ip]; // dF/dS = { M [T * -dPc/dS1] + dM/dS1 * DPhi , M [T * dPc/dS2] + dM/dS2 * DPhi // } } + potGrad_ip[ip] = potGrad; + alpha_ip[ip] = alpha; + + } // loop over phases + if (std::fabs(jFMultiplier[0][0] - jFMultiplier[0][1]) < 1e-8 && std::fabs(jFMultiplier[1][0] - jFMultiplier[1][1]) < 1e-8 ) { + for( integer ip = 0; ip < 2; ++ip ) { // populate local flux vector and derivatives stack.localFlux[k[0]*numEqn + ip] += m_dt * fluxVal[ip]; stack.localFlux[k[1]*numEqn + ip] -= m_dt * fluxVal[ip]; @@ -1142,45 +1201,464 @@ class FaceBasedAssemblyInterfaceConditionKernel : public FaceBasedAssemblyKernel } // Customize the kernel with this lambda - kernelOp( k, seri, sesri, sei, connectionIndex, alpha, mobility, potGrad, fluxVal, dFlux_dP, dFlux_dS ); // Not sure what this - - // does + kernelOp( k, seri, sesri, sei, connectionIndex, alpha_ip[ip], mobility, potGrad_ip[ip], fluxVal, dFlux_dP, dFlux_dS ); // Not sure what this + + }// does + } else { - } // loop over phases + - if( m_hasCapPressure ) - { // std::cout << GEOS_FMT( " uT = ( {:4.2e} )", uT ); // std::cout << GEOS_FMT( " duTdP = ( {:4.2e} )", duT_dP[0] ); // std::cout << GEOS_FMT( " duTdS = ( {:4.2e} )", duT_dS[0] ); - std::cout << GEOS_FMT( " Pc1 = ( {:4.2e} )", capPresIC[0][0] ); - std::cout << GEOS_FMT( " Pc2 = ( {:4.2e} )", capPresIC[0][1] ); - + std::cout << GEOS_FMT( " Pc1 = ( {:4.2e} )", capPresIC[1][0] ); + std::cout << GEOS_FMT( " Pc2 = ( {:4.2e} )", capPresIC[1][1] ); + std::cout << GEOS_FMT( " T1 = ( {:4.2e} )", trans[0] ); + std::cout << GEOS_FMT( " T2 = ( {:4.2e} )", trans[1] ); + std::cout << GEOS_FMT( " That1 = ( {:4.2e} )", transHat[0] ); + std::cout << GEOS_FMT( " That2 = ( {:4.2e} )", transHat[1] ); + // -------------------- Here I implement the interface conditions local solver --------------------- // + // nonlinear solver's parameters + real64 tol = 1.0e-7; + int max_iter = 50; + // initial guess: real64 S_int[numEqn]{}; - real64 const Pc1 = capPresIC[0][0]; - real64 const Pc2 = capPresIC[0][1]; + real64 const Pc1 = capPresIC[1][0]; + real64 const Pc2 = capPresIC[1][1]; + + real64 Pc_int = ( Pc1 + Pc2 ) / 2; + // std::cout << GEOS_FMT( " Pc_int = ( {:4.2e} )", Pc_int ); + // // Local newton loop: + + // Use of the capillary pressure kernel wrapper + + StackArray< real64, 2, 2, immiscibleFlow::LAYOUT_PHASE > facePhaseVolFrac1( 1, 2 ); + StackArray< real64, 3, 2, constitutive::cappres::LAYOUT_CAPPRES > faceCapPres1( 1, 1, 2 ); + StackArray< real64, 4, 4, constitutive::cappres::LAYOUT_CAPPRES_DS > dfacePhaseVolFrac_dCapPres1( 1, 1, 2, 2 ); + StackArray< real64, 2, 2, immiscibleFlow::LAYOUT_PHASE > facePhaseVolFrac2( 1, 2 ); + StackArray< real64, 3, 2, constitutive::cappres::LAYOUT_CAPPRES > faceCapPres2( 1, 1, 2 ); + StackArray< real64, 4, 4, constitutive::cappres::LAYOUT_CAPPRES_DS > dfacePhaseVolFrac_dCapPres2( 1, 1, 2, 2 ); + StackArray< real64, 1, 4> JFunc1( 2 ); + StackArray< real64, 1, 4> JFunc2( 2 ); + + + // Use of the relative permeability kernel wrapper + + StackArray< real64, 3, 2, constitutive::relperm::LAYOUT_RELPERM > faceTrappedVolFrac1( 1, 1, 2 ); + StackArray< real64, 3, 2, constitutive::relperm::LAYOUT_RELPERM > faceRelPerm1( 1, 1, 2 ); + StackArray< real64, 4, 4, constitutive::relperm::LAYOUT_RELPERM_DS > dfacePhaseRelPerm1_dPhaseVolFrac( 1, 1, 2, 2 ); + StackArray< real64, 3, 2, constitutive::relperm::LAYOUT_RELPERM > faceTrappedVolFrac2( 1, 1, 2 ); + StackArray< real64, 3, 2, constitutive::relperm::LAYOUT_RELPERM > faceRelPerm2( 1, 1, 2 ); + StackArray< real64, 4, 4, constitutive::relperm::LAYOUT_RELPERM_DS > dfacePhaseRelPerm2_dPhaseVolFrac( 1, 1, 2, 2 ); + + real64 halfFluxVal[numEqn][2]{}; + real64 dhalfFlux_dP[numEqn][4]{}; + real64 dhalfFlux_dS[numEqn][4]{}; + real64 dhalfFlux_duT[numEqn][2]{}; + + // While loop + int iter = 0; + + + while (iter < max_iter) { + // clear working arrays + + // densMean = {0 , 0}; + // dDensMean_dP[numEqn][0] = {0 , 0}; + // dDensMean_dP[numEqn][1] = {0 , 0}; + + // presGrad[numEqn] = {0 , 0}; + // dPresGrad_dP[numEqn][0] = {0 , 0}; + // dPresGrad_dP[numEqn][1] = {0 , 0}; + + // gravHead[numEqn] = {0 , 0}; + // dGravHead_dP[numEqn][0] = {0 , 0}; + // dGravHead_dP[numEqn][1] = {0 , 0}; + + // capGrad[numEqn] = {0 , 0}; + // capPresIC[numEqn][0] = {0 , 0}; + // capPresIC[numEqn][1] = {0 , 0}; + // dCapGrad_dP[numEqn][0] = {0 , 0}; + // dCapGrad_dP[numEqn][1] = {0 , 0}; + // dCapGrad_dS[numEqn][0] = {0 , 0}; + // dCapGrad_dS[numEqn][1] = {0 , 0}; + // dCapPresIC_dS[numEqn][0] = {0 , 0}; + // dCapPresIC_dS[numEqn][1] = {0 , 0}; + + // fluxVal[numEqn][0] = {0 , 0}; + // fluxVal[numEqn][1] = {0 , 0}; + // dFlux_dP[numEqn][0] = {0 , 0}; + // dFlux_dP[numEqn][1] = {0 , 0}; + // dFlux_dP[numEqn][2] = {0 , 0}; + // dFlux_dP[numEqn][3] = {0 , 0}; + // dFlux_dS[numEqn][0] = {0 , 0}; + // dFlux_dS[numEqn][1] = {0 , 0}; + // dFlux_dS[numEqn][2] = {0 , 0}; + // dFlux_dS[numEqn][3] = {0 , 0}; + + + + real64 density[numEqn]{}; + real64 dDens_dP[numEqn][2]{}; + real64 viscosity[numEqn]{}; + real64 dVisc_dP[numEqn][2]{}; + + // mobility[numEqn] = {0 , 0}; + // dMob_dP[numEqn][0] = {0 , 0}; + // dMob_dP[numEqn][1] = {0 , 0}; + // dMob_dS[numEqn][0] = {0 , 0}; + // dMob_dS[numEqn][1] = {0 , 0}; + + real64 local_residual = 0; + real64 local_jacobian = 0; + + + // Compute the inverse: + faceCapPres1[0][0][1] = Pc_int; + faceCapPres2[0][0][1] = Pc_int; + JFunc1[0] = jFMultiplier[0][0]; + JFunc2[0] = jFMultiplier[0][1]; + + + m_capPressureWrapper.computeInv( facePhaseVolFrac1[0], + JFunc1.toSliceConst(), + faceCapPres1[0][0], + dfacePhaseVolFrac_dCapPres1[0][0]); + + m_capPressureWrapper.computeInv( facePhaseVolFrac2[0], + JFunc2.toSliceConst(), + faceCapPres2[0][0], + dfacePhaseVolFrac_dCapPres2[0][0]); + + // compute relative permeability for both cells: + m_relPermWrapper.compute( facePhaseVolFrac1[0], + faceTrappedVolFrac1[0][0], + faceRelPerm1[0][0], + dfacePhaseRelPerm1_dPhaseVolFrac[0][0]); + + m_relPermWrapper.compute( facePhaseVolFrac2[0], + faceTrappedVolFrac2[0][0], + faceRelPerm2[0][0], + dfacePhaseRelPerm2_dPhaseVolFrac[0][0]); + + + // real64 Sw_alpha = facePhaseVolFrac1[0][0]; + // real64 Sw_beta = facePhaseVolFrac2[0][0]; + // std::cout << GEOS_FMT( " Sw_alpha = ( {:4.2e} )", Sw_alpha ); + // std::cout << GEOS_FMT( " Sw_beta = ( {:4.2e} )", Sw_beta ); + + // real64 Sn_alpha = facePhaseVolFrac1[0][1]; + // real64 Sn_beta = facePhaseVolFrac2[0][1]; + // std::cout << GEOS_FMT( " Sn_alpha = ( {:4.2e} )", Sn_alpha ); + // std::cout << GEOS_FMT( " Sn_beta = ( {:4.2e} )", Sn_beta ); + + // std::cout << GEOS_FMT( " Krw_alpha = ( {:4.2e} )", faceRelPerm1[0][0][0] ); + // std::cout << GEOS_FMT( " Krn_alpha = ( {:4.2e} )", faceRelPerm1[0][0][1] ); + + + + for( integer ix = 0; ix < 2; ++ix ) // for loop for each interface + { + // loop over phases + // clear arrays: + presGrad[0] = 0; + presGrad[1] = 0; + gravHead[0] = 0; + gravHead[1] = 0; + dGravHead_dP[0][0] = 0; + dGravHead_dP[0][1] = 0; + dGravHead_dP[1][0] = 0; + dGravHead_dP[1][1] = 0; + capGrad[0] = 0; + capGrad[1] = 0; + dCapGrad_dP[0][0] = 0; + dCapGrad_dP[1][0] = 0; + dCapGrad_dP[0][1] = 0; + dCapGrad_dP[1][1] = 0; + + for( integer ip = 0; ip < m_numPhases; ++ip ) + { + // calculate quantities on primary connected cells + // density + density[ip] = m_dens[seri[ix]][sesri[ix]][sei[ix]][0][ip]; // r = rho1 || rho2 + dDens_dP[ip][ix] = m_dDens_dPres[seri[ix]][sesri[ix]][sei[ix]][0][ip][Deriv::dP]; // dr/dP = dr1/dP1 || dr2/dP + + viscosity[ip] = m_visc[seri[ix]][sesri[ix]][sei[ix]][0][ip]; // r = rho1 || rho2 + dVisc_dP[ip][ix] = m_dVisc_dPres[seri[ix]][sesri[ix]][sei[ix]][0][ip][Deriv::dP]; // dr/dP = dr1/dP1 || dr2/dP + + densMean[ip] = density[ip]; // rho = (rho1 + rho2) + dDensMean_dP[ip][0] = dDens_dP[ip][ix]; // drho/dP = { (dr1/dP1) , (dr2/dP2) } + dDensMean_dP[ip][1] = dDens_dP[ip][ix]; + + //***** calculation of flux ***** + + // compute potential difference + real64 potScale = 0.0; + real64 dPresGrad_dTrans = 0.0; + real64 dGravHead_dTrans = 0.0; + real64 dCapGrad_dTrans = 0.0; + constexpr int signPotDiff[2] = {1, -1}; + + for( integer ke = 0; ke < 2; ++ke ) + { + localIndex const er = seri[ix]; + localIndex const esr = sesri[ix]; + localIndex const ei = sei[ix]; + + real64 const pressure = m_pres[er][esr][ei]; // P = P1 || P2 + presGrad[ip] += transHat[ix] * pressure; // DPv = T (P1 - P2) + dPresGrad_dTrans += signPotDiff[ke] * pressure; // dDPv/dT = (P1 - P2) + dPresGrad_dP[ip][ke] = transHat[ix]; // dDPv/dP = { T , -T } + + real64 const gravD = transHat[ix] * gravCoefHat[ix]; // D = T g z1 || -T g z2 + real64 pot = transHat[ix] * pressure - densMean[ip] * gravD; // Phi = T P1 - rho T g z1 || -T P2 + rho T g z2 + + gravHead[ip] += densMean[ip] * gravD; // DPg = rho (T g z1 - T g z2) = T rho g (z1 - z2) + dGravHead_dTrans += signPotDiff[ke] * densMean[ip] * gravCoefHat[ix]; // dDPg/dT = rho g z1 - rho g z2 = rho g (z1 - z2) + + for( integer i = 0; i < 2; ++i ) + { + dGravHead_dP[ip][i] += dDensMean_dP[ip][i] * gravD; // dDPg/dP = {drho/dP1 * T g (z1 - z2) , drho/dP2 * T g (z1 - z2)} + } + + if( m_hasCapPressure ) // check sign convention + { + real64 capPres = m_phaseCapPressure[er][esr][ei][0][ip]; // Pc = Pc1 || Pc2 + + if( ke == 1 && ix == 0 ) { + capPres = faceCapPres1[0][0][ip]; + } else if ( ke == 1 && ix == 1 ) { + capPres = faceCapPres2[0][0][ip]; + } + + dCapGrad_dTrans -= signPotDiff[ke] * capPres; // dDPc/dT = (-Pc1 + Pc2) + pot -= transHat[ix] * capPres; // Phi = T P1 - rho T g z1 - T Pc1 || -T P2 + rho T g z2 + T + // Pc2 + capGrad[ip] -= transHat[ix] * capPres; // DPc = T (-Pc1 + Pc2) + } + + potScale = fmax( potScale, fabs( pot ) ); // maxPhi = Phi1 > Phi2 ? Phi1 : Phi2 + } + + for( integer ke = 0; ke < 2; ++ke ) + { + dPresGrad_dP[ip][ke] += dTransHat_dP[ix] * dPresGrad_dTrans; // dDPv/dP = { T + dT/dP1 * (P1 - P2) , -T + dT/dP2 * (P1 - P2)} + dGravHead_dP[ip][ke] += dTransHat_dP[ix] * dGravHead_dTrans; // dDPg/dP = { drho/dP1 * T g (z1 - z2) + dT/dP1 * rho g (z1 - z2) , + // drho/dP2 * T g (z1 - z2) + dT/dP2 * rho g (z1 - z2) } + if( m_hasCapPressure ) + { + real64 constexpr eps = 1e-8; + real64 dCapPres_dS = m_dPhaseCapPressure_dPhaseVolFrac[seri[ix]][sesri[ix]][sei[ix]][0][ip][ip]; // dPc/dS = dPc1/dS1 || + + + if( ke == 1 && ix == 0 ) { + real64 dCapPresIC_dS = dfacePhaseVolFrac_dCapPres1[0][0][ip][ip]; + dCapPres_dS = 1 / ( dCapPresIC_dS + eps); + } else if ( ke == 1 && ix == 1 ) { + real64 dCapPresIC_dS = dfacePhaseVolFrac_dCapPres2[0][0][ip][ip]; + dCapPres_dS = 1 / ( dCapPresIC_dS + eps); + } + // dPc2/dS2 + dCapGrad_dP[ip][ke] += dTransHat_dP[ix] * dCapGrad_dTrans; // dDPc/dP = { dT/dP1 * + // (-Pc1 + Pc2) , + // dT/dP2 * + // (-Pc1 + Pc2) } + dCapGrad_dS[ip][ke] -= transHat[ix] * dCapPres_dS; // dDPc/dS = { -T * + // dPc1/dS1 , T * + // dPc2/dS2 } + } + } + + // *** upwinding *** + + // compute potential gradient + real64 potGrad = presGrad[ip] - gravHead[ip]; // DPhi = T (P1 - P2) - T rho g (z1 - z2) + if( m_hasCapPressure ) + { + potGrad += capGrad[ip]; // DPhi = T (P1 - P2) - T rho g (z1 - z2) + T (-Pc1 + Pc2) + } - real64 const Pc_int = ( Pc1 + Pc2 ) / 2; + // compute upwinding tolerance + real64 constexpr upwRelTol = 1e-8; + real64 const upwAbsTol = fmax( potScale * upwRelTol, LvArray::NumericLimits< real64 >::epsilon ); // abstol = maxPhi * tol > eps ? + // maxPhi * tol : eps - // Local newton loop: + // decide mobility coefficients - smooth variation in [-upwAbsTol; upwAbsTol] + real64 const alpha = ( potGrad + upwAbsTol ) / ( 2 * upwAbsTol ); // alpha = (DPhi + abstol) / abstol / 2 - // compute S_alpha and S_beta: - S_int[0] = computePCalphaInv< arrayView1d< real64 const > >( Pc_int ); - S_int[1] = computePCalphaInv< arrayView1d< real64 const > >( Pc_int ); + // choose upstream cell + // if( alpha <= 0.0 || alpha >= 1.0 ) // no smoothing needed + // { + constexpr int sign[2] = {1, -1}; - real64 S_avg = S_int[0] + S_int[1]; + localIndex const k_up = 1 - localIndex( fmax( fmin( alpha, 1.0 ), 0.0 ) ); // 1 upwind -> k_up = 0 || 2 upwind -> k_up = 1 - // real64 PC_int1 = computePCalphaInv > ( S_int[0] ); - // real64 PC_int2 = computePCalphaInv > ( S_int[1] ); - GEOS_UNUSED_PARAM( S_avg ); + if( k_up == 1 && ix == 0 ) { + + mobility[ip] = faceRelPerm1[0][ip][ip] * density[ip] / viscosity[ip]; // M = Mupstream + dMob_dP[ip][k_up] = mobility[ip] * (dDens_dP[ip][ip] / density[ip] - dVisc_dP[ip][ip] / viscosity[ip]); // dM/dP = {dM/dP1 , 0} OR {0 , dM/dP2} + dMob_dS[ip][k_up] = dfacePhaseRelPerm1_dPhaseVolFrac[0][0][ip][ip] * density[ip] / viscosity[ip]; // dM/dS = {dM/dS1 , 0} OR {0 , dM/dS2} + } else if ( k_up == 1 && ix == 1 ) { + mobility[ip] = faceRelPerm2[0][ip][ip] * density[ip] / viscosity[ip]; // M = Mupstream + dMob_dP[ip][k_up] = mobility[ip] * (dDens_dP[ip][ip] / density[ip] - dVisc_dP[ip][ip] / viscosity[ip]); // dM/dP = {dM/dP1 , 0} OR {0 , dM/dP2} + dMob_dS[ip][k_up] = dfacePhaseRelPerm2_dPhaseVolFrac[0][0][ip][ip] * density[ip] / viscosity[ip]; // dM/dS = {dM/dS1 , 0} OR {0 , dM/dS2} + } else { + mobility[ip] = m_mob[seri[k_up]][sesri[k_up]][sei[k_up]][ip]; // M = Mupstream + dMob_dP[ip][k_up] = m_dMob[seri[k_up]][sesri[k_up]][sei[k_up]][ip][Deriv::dP]; // dM/dP = {dM/dP1 , 0} OR {0 , dM/dP2} + dMob_dS[ip][k_up] = m_dMob[seri[k_up]][sesri[k_up]][sei[k_up]][ip][Deriv::dS]; // dM/dS = {dM/dS1 , 0} OR {0 , dM/dS2} + } + + + // } + // else // perform smoothing + // { + // real64 const mobWeights[2] = { alpha, 1.0 - alpha }; + // for( integer ke = 0; ke < 2; ++ke ) + // { + + // mobility[ip] += mobWeights[ke] * m_mob[seri[ke]][sesri[ke]][sei[ke]][ip]; // M = alpha * M1 + (1 - alpha) * M2 + // density2[ip] += mobWeights[ke] * m_dens[seri[ke]][sesri[ke]][sei[ke]][0][ip]; // r = rho1 || rho2 + // dDens_dP2[ip][ke] = mobWeights[ke] * m_dDens_dPres[seri[ke]][sesri[ke]][sei[ke]][0][ip][Deriv::dP]; // dr/dP = dr1/dP1 || + // // dr2/dP + // dMob_dP[ip][ke] = mobWeights[ke] * m_dMob[seri[ke]][sesri[ke]][sei[ke]][ip][Deriv::dP]; // dM/dP = {alpha * dM1/dP1 , (1 - + // // alpha) * dM2/dP2} + // dMob_dS[ip][ke] = mobWeights[ke] * m_dMob[seri[ke]][sesri[ke]][sei[ke]][ip][Deriv::dS]; // dM/dP = {alpha * dM1/dS1 , (1 - + // // alpha) * dM2/dS2} + // } + // } + real64 constexpr eps = 0.5e-8; + total_mobility += mobility[ip] + eps; + potGrad_ip[ip] = potGrad; + alpha_ip[ip] = alpha; + + } // loop over phases + + /// Three Forces Flux Contribution: 1- Viscous 2- Gravitational 3- Capillary + // loop over phases + for( integer ip = 0; ip < m_numPhases; ++ip ) + { + // 1- Viscous: pressure gradient depends on all points in the stencil + for( integer ke = 0; ke < 2; ++ke ) + { + halfFluxVal[ip][ix] = mobility[ip] / total_mobility * uT; + dhalfFlux_dP[ip][ix + ke] = dPresGrad_dP[ip][ke]; // dF/dP = { T + dT/dP1 * (P1 - P2) , + // -T + dT/dP2 * (P1 - P2) } + } + + // 2- Gravitational: gravitational head depends only on the two cells connected (same as mean density) + for( integer ke = 0; ke < 2; ++ke ) + { + halfFluxVal[ip][ix] -= mobility[0] * mobility[1] / total_mobility * gravHead[ip]; + dhalfFlux_dP[ip][ix + ke] -= dGravHead_dP[ip][ke]; // dF/dP = { T + dT/dP1 * (P1 - P2) - drho/dP1 * T g (z1 - z2) - dT/dP1 * rho g (z1 - + // z2) , + // -T + dT/dP2 * (P1 - P2) - drho/dP2 * T g (z1 - z2) - dT/dP2 * rho g (z1 - + // z2) } + } + + // 3- Capillary: capillary pressure contribution + if( m_hasCapPressure ) + { + for( integer ke = 0; ke < 2; ++ke ) + { + halfFluxVal[ip][ix] += mobility[0] * mobility[1] / total_mobility * capGrad[ip]; + dhalfFlux_dP[ip][ix + ke] += dCapGrad_dP[ip][ke]; // dF/dP = { T + dT/dP1 * (P1 - P2) - drho/dP1 * T g (z1 - z2) - dT/dP1 * rho g (z1 + // - z2) + dT/dP1 * (-Pc1 + Pc2) , + // -T + dT/dP2 * (P1 - P2) - drho/dP2 * T g (z1 - z2) - dT/dP2 * rho g (z1 + // - z2) + dT/dP2 * (-Pc1 + Pc2) } + + dhalfFlux_dS[ip][ix + ke] = dCapGrad_dS[ip][ke]; // dF/dS = { T * -dPc/dS1 , T * dPc/dS2 } + } + } + + + for( integer ke = 0; ke < 2; ++ke ) + { + dhalfFlux_dP[ip][ix + ke] *= mobility[ip]; // dF/dP = { M [ T + dT/dP1 * (P1 - P2) - drho/dP1 * T g (z1 - z2) - dT/dP1 * rho g (z1 - + // z2) + dT/dP1 * (-Pc1 + Pc2)] , + // M [-T + dT/dP2 * (P1 - P2) - drho/dP2 * T g (z1 - z2) - dT/dP2 * rho g (z1 - + // z2) + dT/dP2 * (-Pc1 + Pc2)] } + + dhalfFlux_dS[ip][ix + ke] *= mobility[ip]; // dF/dS = { M [T * -dPc/dS1] , M [T * dPc/dS2] } + } + + // add contribution from upstream cell mobility derivatives + for( integer ke = 0; ke < 2; ++ke ) + { + dhalfFlux_dP[ip][ix + ke] += dMob_dP[ip][ke] * potGrad_ip[ip]; // dF/dP = { M [ T + dT/dP1 * (P1 - P2) - drho1/dP * T g (z1 - z2) - dT/dP1 * + // rho g (z1 - z2) + dT/dP1 * (-Pc1 + Pc2)] + dM/dP1 * DPhi , + // M [-T + dT/dP2 * (P1 - P2) - drho2/dP * T g (z1 - z2) - dT/dP2 * + // rho g (z1 - z2) + dT/dP2 * (-Pc1 + Pc2)] + dM/dP2 * DPhi } + dhalfFlux_dS[ip][ix + ke] += dMob_dS[ip][ke] * potGrad_ip[ip]; // dF/dS = { M [T * -dPc/dS1] + dM/dS1 * DPhi , M [T * dPc/dS2] + dM/dS2 * DPhi + // } } + // does + + } // loop over phases + + } // loop over half fluxes + + local_jacobian = dhalfFlux_dS[1][1]*dfacePhaseVolFrac_dCapPres1[0][0][1][1] - dhalfFlux_dS[1][3]*dfacePhaseVolFrac_dCapPres2[0][0][1][1]; + local_residual = halfFluxVal[1][0] - halfFluxVal[1][1]; + + real64 deltaPc = local_residual/local_jacobian; + Pc_int -= deltaPc; + + iter++; + + // Check convergence + if (std::fabs(local_residual) < tol) { + break; // Converged + } + + + } + + for( integer ip = 0; ip < m_numPhases; ++ip ) + { + // populate local flux vector and derivatives + stack.localFlux[k[0]*numEqn + ip] += m_dt * (halfFluxVal[ip][0] + halfFluxVal[ip][1]); + stack.localFlux[k[1]*numEqn + ip] -= m_dt * (halfFluxVal[ip][0] + halfFluxVal[ip][1]); + + for( integer ke = 0; ke < 2; ++ke ) + { + // pressure + localIndex const localDofIndexPres = k[ke] * numDof; + stack.localFluxJacobian[k[0]*numEqn + ip][localDofIndexPres] += m_dt * dhalfFlux_dP[ip][ke]; + stack.localFluxJacobian[k[1]*numEqn + ip][localDofIndexPres] -= m_dt * dhalfFlux_dP[ip][ke]; + + // saturation (hard-coded for 2-phase currently) + localIndex const localDofIndexSat = k[ke] * numDof + 1; + stack.localFluxJacobian[k[0]*numEqn + ip][localDofIndexSat] += m_dt * dhalfFlux_dS[ip][ke]; + stack.localFluxJacobian[k[1]*numEqn + ip][localDofIndexSat] -= m_dt * dhalfFlux_dS[ip][ke]; + } + + // Customize the kernel with this lambda + kernelOp( k, seri, sesri, sei, connectionIndex, alpha_ip[ip], mobility, potGrad_ip[ip], fluxVal, dFlux_dP, dFlux_dS ); // Not sure what this + + + // } +// // // compute S_alpha and S_beta: + // S_int[0] = computePCalphaInv< arrayView1d< real64 const > >( Pc_int ); + // S_int[1] = computePCalphaInv< arrayView1d< real64 const > >( Pc_int ); + + // real64 S_avg = S_int[0] + S_int[1]; + + // // real64 PC_int1 = computePCalphaInv > ( S_int[0] ); + // // real64 PC_int2 = computePCalphaInv > ( S_int[1] ); + + + + // GEOS_UNUSED_PARAM( Pc_int ); + + } // loop over phases + } // end of else for interface conditions connectionIndex++; } } // loop over connection elements @@ -1189,6 +1667,7 @@ class FaceBasedAssemblyInterfaceConditionKernel : public FaceBasedAssemblyKernel /// Reference to the capillary pressure wrapper CAPPRESWRAPPER const m_capPressureWrapper; + RELPERMWRAPPER const m_relPermWrapper; }; @@ -1264,7 +1743,7 @@ class FaceBasedAssemblyKernelFactory * @param[inout] localMatrix the local CRS matrix * @param[inout] localRhs the local right-hand side vector */ - template< typename POLICY, typename STENCILWRAPPER, typename CAPPRESWRAPPER > + template< typename POLICY, typename STENCILWRAPPER, typename CAPPRESWRAPPER, typename RELPERMWRAPPER > static void createAndLaunch( integer const numPhases, globalIndex const rankOffset, @@ -1276,28 +1755,31 @@ class FaceBasedAssemblyKernelFactory ElementRegionManager const & elemManager, STENCILWRAPPER const & stencilWrapper, CAPPRESWRAPPER const & capPresWrapper, + RELPERMWRAPPER const & relPermWrapper, + ElementSubRegionBase const & subRegion, real64 const & dt, CRSMatrixView< real64, globalIndex const > const & localMatrix, arrayView1d< real64 > const & localRhs ) { integer constexpr NUM_EQN = 2; integer constexpr NUM_DOF = 2; - + localIndex const domainSize = subRegion.size(); + // GEOS_UNUSED_PARAM( domainSize ); ElementRegionManager::ElementViewAccessor< arrayView1d< globalIndex const > > dofNumberAccessor = elemManager.constructArrayViewAccessor< globalIndex, 1 >( dofKey ); dofNumberAccessor.setName( solverName + "/accessors/" + dofKey ); - using kernelType = FaceBasedAssemblyInterfaceConditionKernel< NUM_EQN, NUM_DOF, STENCILWRAPPER, CAPPRESWRAPPER >; + using kernelType = FaceBasedAssemblyInterfaceConditionKernel< NUM_EQN, NUM_DOF, STENCILWRAPPER, CAPPRESWRAPPER, RELPERMWRAPPER >; typename kernelType::ImmiscibleMultiphaseFlowAccessors flowAccessors( elemManager, solverName ); typename kernelType::MultiphaseFluidAccessors fluidAccessors( elemManager, solverName ); typename kernelType::CapPressureAccessors capPressureAccessors( elemManager, solverName ); typename kernelType::PermeabilityAccessors permAccessors( elemManager, solverName ); - kernelType kernel( numPhases, rankOffset, stencilWrapper, capPresWrapper, dofNumberAccessor, + kernelType kernel( numPhases, rankOffset, stencilWrapper, capPresWrapper, relPermWrapper, dofNumberAccessor, flowAccessors, fluidAccessors, capPressureAccessors, permAccessors, dt, localMatrix, localRhs, hasCapPressure, useTotalMassEquation, - checkPhasePresenceInGravity ); - kernelType::template launch< POLICY >( stencilWrapper.size(), kernel ); + checkPhasePresenceInGravity, domainSize); + kernelType::template launch< POLICY >( stencilWrapper.size() , kernel ); } }; From b47698e5ec0a7d8eb3c78ed9c9705c66959115c7 Mon Sep 17 00:00:00 2001 From: Ammara-14 Date: Fri, 9 May 2025 14:02:08 -0700 Subject: [PATCH 092/102] updates to the array indices --- .../ImmiscibleMultiphaseKernels.hpp | 318 ++++++++++-------- 1 file changed, 169 insertions(+), 149 deletions(-) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp index fa6b6f69d17..a8d38df9229 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp @@ -101,6 +101,7 @@ class FaceBasedAssemblyKernelBase fields::flow::gravityCoefficient, fields::immiscibleMultiphaseFlow::phaseVolumeFraction, fields::immiscibleMultiphaseFlow::phaseMobility, + fields::immiscibleMultiphaseFlow::phaseMass_n, fields::immiscibleMultiphaseFlow::dPhaseMobility >; using MultiphaseFluidAccessors = @@ -161,6 +162,7 @@ class FaceBasedAssemblyKernelBase m_gravCoef( multiPhaseFlowAccessors.get( fields::flow::gravityCoefficient {} ) ), m_pres( multiPhaseFlowAccessors.get( fields::flow::pressure {} ) ), m_phaseVolFrac( multiPhaseFlowAccessors.get( fields::immiscibleMultiphaseFlow::phaseVolumeFraction {} ) ), + m_phaseMass_n( multiPhaseFlowAccessors.get( fields::immiscibleMultiphaseFlow::phaseMass_n {} ) ), m_mob( multiPhaseFlowAccessors.get( fields::immiscibleMultiphaseFlow::phaseMobility {} ) ), m_dMob( multiPhaseFlowAccessors.get( fields::immiscibleMultiphaseFlow::dPhaseMobility {} ) ), m_dens( fluidAccessors.get( fields::twophasefluid::phaseDensity {} ) ), @@ -203,6 +205,7 @@ class FaceBasedAssemblyKernelBase /// Views on pressure and phase volume fraction ElementViewConst< arrayView1d< real64 const > > const m_pres; ElementViewConst< arrayView2d< real64 const, immiscibleFlow::USD_PHASE > > const m_phaseVolFrac; + ElementViewConst< arrayView2d< real64 const, immiscibleFlow::USD_PHASE > > const m_phaseMass_n; /// Views on fluid mobility ElementViewConst< arrayView2d< real64 const, immiscibleFlow::USD_PHASE > > const m_mob; @@ -804,6 +807,7 @@ class FaceBasedAssemblyInterfaceConditionKernel : public FaceBasedAssemblyKernel using Base::m_permeability; using Base::m_dPerm_dPres; using Base::m_phaseVolFrac; + using Base::m_phaseMass_n; using Base::m_phaseCapPressure; using Base::m_jFuncMultiplier; using Base::m_dPhaseCapPressure_dPhaseVolFrac; @@ -901,6 +905,25 @@ class FaceBasedAssemblyInterfaceConditionKernel : public FaceBasedAssemblyKernel localIndex k[2]; localIndex connectionIndex = 0; + // // Create an output file stream object (ofstream) + // std::ofstream outFile("iterations.csv"); + + + // // Write data to the file + // outFile << "Jacobian"; + // outFile << ","; + // outFile << "residual"; + // outFile << ","; + // outFile << "F_alpha"; + // outFile << ","; + // outFile << "F_beta"; + // outFile << ","; + // outFile << "Pc"; + // outFile << ","; + // outFile << "newton"; + // outFile << std::endl; + + m_stencilWrapper.computeHalfWeights( iconn, m_permeability, m_dPerm_dPres, @@ -1041,10 +1064,6 @@ class FaceBasedAssemblyInterfaceConditionKernel : public FaceBasedAssemblyKernel potScale = fmax( potScale, fabs( pot ) ); // maxPhi = Phi1 > Phi2 ? Phi1 : Phi2 } - // std::cout << GEOS_FMT( " z1 = ( {:4.2e} )", m_gravCoef[seri[0]][sesri[0]][sei[0]] ); - // std::cout << GEOS_FMT( " z2 = ( {:4.2e} )", m_gravCoef[seri[1]][sesri[1]][sei[1]] ); - // std::cout << GEOS_FMT( " zhat1 = ( {:4.2e} )", gravCoefHat[0] ); - // std::cout << GEOS_FMT( " zhat2 = ( {:4.2e} )", gravCoefHat[1] ); for( integer ke = 0; ke < 2; ++ke ) { @@ -1168,18 +1187,19 @@ class FaceBasedAssemblyInterfaceConditionKernel : public FaceBasedAssemblyKernel // add contribution from upstream cell mobility derivatives for( integer ke = 0; ke < 2; ++ke ) { - duT_dP[ke] += dFlux_dP[ip][ke] - fluxVal[ip] * dDens_dP2[ip][ke] / density2[ip]; // dF/dP = { M [ T + dT/dP1 * (P1 - P2) - - // drho1/dP * T g (z1 - z2) - dT/dP1 * - duT_dP[ke] /= density2[ip]; // rho g (z1 - z2) + dT/dP1 * (-Pc1 + Pc2)] + dM/dP1 * DPhi , - // M [-T + dT/dP2 * (P1 - P2) - drho2/dP * T g (z1 - z2) - dT/dP2 * - // rho g (z1 - z2) + dT/dP2 * (-Pc1 + Pc2)] + dM/dP2 * DPhi } - duT_dS[ke] += dFlux_dS[ip][ke] / density2[ip]; // dF/dS = { M [T * -dPc/dS1] + dM/dS1 * DPhi , M [T * dPc/dS2] + dM/dS2 * DPhi - // } + duT_dP[ke] += dFlux_dP[ip][ke] - fluxVal[ip] * dDens_dP2[ip][ke] / density2[ip]; + + duT_dP[ke] /= density2[ip]; + duT_dS[ke] += dFlux_dS[ip][ke] / density2[ip]; } + potGrad_ip[ip] = potGrad; alpha_ip[ip] = alpha; } // loop over phases + // std::cout << GEOS_FMT( " Pc1 = ( {:4.2e} )", capPresIC[1][0] ); + // std::cout << GEOS_FMT( " Pc2 = ( {:4.2e} )", capPresIC[1][1] ); + if (std::fabs(jFMultiplier[0][0] - jFMultiplier[0][1]) < 1e-8 && std::fabs(jFMultiplier[1][0] - jFMultiplier[1][1]) < 1e-8 ) { for( integer ip = 0; ip < 2; ++ip ) { @@ -1206,24 +1226,14 @@ class FaceBasedAssemblyInterfaceConditionKernel : public FaceBasedAssemblyKernel }// does } else { - - - // std::cout << GEOS_FMT( " uT = ( {:4.2e} )", uT ); - // std::cout << GEOS_FMT( " duTdP = ( {:4.2e} )", duT_dP[0] ); - // std::cout << GEOS_FMT( " duTdS = ( {:4.2e} )", duT_dS[0] ); - std::cout << GEOS_FMT( " Pc1 = ( {:4.2e} )", capPresIC[1][0] ); - std::cout << GEOS_FMT( " Pc2 = ( {:4.2e} )", capPresIC[1][1] ); - std::cout << GEOS_FMT( " T1 = ( {:4.2e} )", trans[0] ); - std::cout << GEOS_FMT( " T2 = ( {:4.2e} )", trans[1] ); - std::cout << GEOS_FMT( " That1 = ( {:4.2e} )", transHat[0] ); - std::cout << GEOS_FMT( " That2 = ( {:4.2e} )", transHat[1] ); + // -------------------- Here I implement the interface conditions local solver --------------------- // // nonlinear solver's parameters real64 tol = 1.0e-7; - int max_iter = 50; + int max_iter = 20; // initial guess: real64 S_int[numEqn]{}; @@ -1231,7 +1241,7 @@ class FaceBasedAssemblyInterfaceConditionKernel : public FaceBasedAssemblyKernel real64 const Pc2 = capPresIC[1][1]; real64 Pc_int = ( Pc1 + Pc2 ) / 2; - // std::cout << GEOS_FMT( " Pc_int = ( {:4.2e} )", Pc_int ); + // std::cout << GEOS_FMT( " Pc_int_old = ( {:4.2e} )", Pc_int ); // // Local newton loop: // Use of the capillary pressure kernel wrapper @@ -1239,12 +1249,53 @@ class FaceBasedAssemblyInterfaceConditionKernel : public FaceBasedAssemblyKernel StackArray< real64, 2, 2, immiscibleFlow::LAYOUT_PHASE > facePhaseVolFrac1( 1, 2 ); StackArray< real64, 3, 2, constitutive::cappres::LAYOUT_CAPPRES > faceCapPres1( 1, 1, 2 ); StackArray< real64, 4, 4, constitutive::cappres::LAYOUT_CAPPRES_DS > dfacePhaseVolFrac_dCapPres1( 1, 1, 2, 2 ); + StackArray< real64, 4, 4, constitutive::cappres::LAYOUT_CAPPRES_DS > dCapPres1_dfacePhaseVolFrac( 1, 1, 2, 2 ); StackArray< real64, 2, 2, immiscibleFlow::LAYOUT_PHASE > facePhaseVolFrac2( 1, 2 ); StackArray< real64, 3, 2, constitutive::cappres::LAYOUT_CAPPRES > faceCapPres2( 1, 1, 2 ); StackArray< real64, 4, 4, constitutive::cappres::LAYOUT_CAPPRES_DS > dfacePhaseVolFrac_dCapPres2( 1, 1, 2, 2 ); + StackArray< real64, 4, 4, constitutive::cappres::LAYOUT_CAPPRES_DS > dCapPres2_dfacePhaseVolFrac( 1, 1, 2, 2 ); StackArray< real64, 1, 4> JFunc1( 2 ); StackArray< real64, 1, 4> JFunc2( 2 ); - + + JFunc1[0] = jFMultiplier[0][0]; + JFunc2[0] = jFMultiplier[0][1]; + + // finding endpoints: + facePhaseVolFrac1[0][0] = 0.0; + facePhaseVolFrac1[0][1] = 1.0; + m_capPressureWrapper.compute( facePhaseVolFrac1[0], + JFunc1.toSliceConst(), + faceCapPres1[0][0], + dCapPres1_dfacePhaseVolFrac[0][0]); + real64 const Pc1_min = faceCapPres1[0][0][1]; + facePhaseVolFrac1[0][0] = 1.0; + facePhaseVolFrac1[0][1] = 0.0; + m_capPressureWrapper.compute( facePhaseVolFrac1[0], + JFunc1.toSliceConst(), + faceCapPres1[0][0], + dCapPres1_dfacePhaseVolFrac[0][0]); + real64 const Pc1_max = faceCapPres1[0][0][1]; + + facePhaseVolFrac2[0][0] = 0.0; + facePhaseVolFrac2[0][1] = 1.0; + m_capPressureWrapper.compute( facePhaseVolFrac2[0], + JFunc2.toSliceConst(), + faceCapPres2[0][0], + dCapPres2_dfacePhaseVolFrac[0][0]); + real64 const Pc2_min = faceCapPres2[0][0][1]; + facePhaseVolFrac2[0][0] = 1.0; + facePhaseVolFrac2[0][1] = 0.0; + m_capPressureWrapper.compute( facePhaseVolFrac2[0], + JFunc2.toSliceConst(), + faceCapPres2[0][0], + dCapPres2_dfacePhaseVolFrac[0][0]); + real64 const Pc2_max = faceCapPres2[0][0][1]; + + + std::cout << GEOS_FMT( " Pc_max1 = ( {:4.2e} )", Pc1_max ); + std::cout << GEOS_FMT( " Pc_min1 = ( {:4.2e} )", Pc1_min ); + std::cout << GEOS_FMT( " Pc_max2 = ( {:4.2e} )", Pc2_max ); + std::cout << GEOS_FMT( " Pc_min2 = ( {:4.2e} )", Pc2_min ); // Use of the relative permeability kernel wrapper @@ -1265,40 +1316,7 @@ class FaceBasedAssemblyInterfaceConditionKernel : public FaceBasedAssemblyKernel while (iter < max_iter) { - // clear working arrays - - // densMean = {0 , 0}; - // dDensMean_dP[numEqn][0] = {0 , 0}; - // dDensMean_dP[numEqn][1] = {0 , 0}; - - // presGrad[numEqn] = {0 , 0}; - // dPresGrad_dP[numEqn][0] = {0 , 0}; - // dPresGrad_dP[numEqn][1] = {0 , 0}; - - // gravHead[numEqn] = {0 , 0}; - // dGravHead_dP[numEqn][0] = {0 , 0}; - // dGravHead_dP[numEqn][1] = {0 , 0}; - - // capGrad[numEqn] = {0 , 0}; - // capPresIC[numEqn][0] = {0 , 0}; - // capPresIC[numEqn][1] = {0 , 0}; - // dCapGrad_dP[numEqn][0] = {0 , 0}; - // dCapGrad_dP[numEqn][1] = {0 , 0}; - // dCapGrad_dS[numEqn][0] = {0 , 0}; - // dCapGrad_dS[numEqn][1] = {0 , 0}; - // dCapPresIC_dS[numEqn][0] = {0 , 0}; - // dCapPresIC_dS[numEqn][1] = {0 , 0}; - - // fluxVal[numEqn][0] = {0 , 0}; - // fluxVal[numEqn][1] = {0 , 0}; - // dFlux_dP[numEqn][0] = {0 , 0}; - // dFlux_dP[numEqn][1] = {0 , 0}; - // dFlux_dP[numEqn][2] = {0 , 0}; - // dFlux_dP[numEqn][3] = {0 , 0}; - // dFlux_dS[numEqn][0] = {0 , 0}; - // dFlux_dS[numEqn][1] = {0 , 0}; - // dFlux_dS[numEqn][2] = {0 , 0}; - // dFlux_dS[numEqn][3] = {0 , 0}; + @@ -1307,21 +1325,27 @@ class FaceBasedAssemblyInterfaceConditionKernel : public FaceBasedAssemblyKernel real64 viscosity[numEqn]{}; real64 dVisc_dP[numEqn][2]{}; - // mobility[numEqn] = {0 , 0}; - // dMob_dP[numEqn][0] = {0 , 0}; - // dMob_dP[numEqn][1] = {0 , 0}; - // dMob_dS[numEqn][0] = {0 , 0}; - // dMob_dS[numEqn][1] = {0 , 0}; real64 local_residual = 0; real64 local_jacobian = 0; - - // Compute the inverse: - faceCapPres1[0][0][1] = Pc_int; - faceCapPres2[0][0][1] = Pc_int; - JFunc1[0] = jFMultiplier[0][0]; - JFunc2[0] = jFMultiplier[0][1]; + real64 Pc_int1 = fmin(Pc1_max, fmax(Pc_int, Pc1_min)); + real64 Pc_int2 = fmin(Pc2_max, fmax(Pc_int, Pc2_min)); + + // std::cout << GEOS_FMT( " Pc_int1 = ( {:4.2e} )", Pc_int1 ); + // std::cout << GEOS_FMT( " Pc_int2 = ( {:4.2e} )", Pc_int2 ); + + // Compute the inverse using pc tilde:: + faceCapPres1[0][0][1] = fmin(Pc2_max, fmax(Pc_int1, Pc2_min)); + faceCapPres2[0][0][1] = fmin(Pc1_max, fmax(Pc_int2, Pc1_min)); + + + std::cout << GEOS_FMT( " faceCapPres1[0][0][1] = ( {:4.2e} )", faceCapPres1[0][0][1] ); + std::cout << GEOS_FMT( " faceCapPres2[0][0][1] = ( {:4.2e} )", faceCapPres2[0][0][1] ); + + std::cout << GEOS_FMT( " faceCapPres1[0][0][0] = ( {:4.2e} )", faceCapPres1[0][0][0] ); + std::cout << GEOS_FMT( " faceCapPres2[0][0][0] = ( {:4.2e} )", faceCapPres2[0][0][0] ); + m_capPressureWrapper.computeInv( facePhaseVolFrac1[0], @@ -1346,22 +1370,31 @@ class FaceBasedAssemblyInterfaceConditionKernel : public FaceBasedAssemblyKernel dfacePhaseRelPerm2_dPhaseVolFrac[0][0]); - // real64 Sw_alpha = facePhaseVolFrac1[0][0]; - // real64 Sw_beta = facePhaseVolFrac2[0][0]; - // std::cout << GEOS_FMT( " Sw_alpha = ( {:4.2e} )", Sw_alpha ); - // std::cout << GEOS_FMT( " Sw_beta = ( {:4.2e} )", Sw_beta ); + // real64 Sw_alpha = facePhaseVolFrac1[0][1]; + // real64 Sw_beta = facePhaseVolFrac2[0][1]; + // // std::cout << GEOS_FMT( " Sw_alpha = ( {:4.2e} )", Sw_alpha ); + // // std::cout << GEOS_FMT( " Sw_beta = ( {:4.2e} )", Sw_beta ); + + // real64 Sn_alpha = facePhaseVolFrac1[0][0]; + // real64 Sn_beta = facePhaseVolFrac2[0][0]; + - // real64 Sn_alpha = facePhaseVolFrac1[0][1]; - // real64 Sn_beta = facePhaseVolFrac2[0][1]; - // std::cout << GEOS_FMT( " Sn_alpha = ( {:4.2e} )", Sn_alpha ); - // std::cout << GEOS_FMT( " Sn_beta = ( {:4.2e} )", Sn_beta ); + //get derivatives: + m_capPressureWrapper.compute( facePhaseVolFrac1[0], + JFunc1.toSliceConst(), + faceCapPres1[0][0], + dCapPres1_dfacePhaseVolFrac[0][0]); - // std::cout << GEOS_FMT( " Krw_alpha = ( {:4.2e} )", faceRelPerm1[0][0][0] ); - // std::cout << GEOS_FMT( " Krn_alpha = ( {:4.2e} )", faceRelPerm1[0][0][1] ); + m_capPressureWrapper.compute( facePhaseVolFrac2[0], + JFunc1.toSliceConst(), + faceCapPres2[0][0], + dCapPres2_dfacePhaseVolFrac[0][0]); + - for( integer ix = 0; ix < 2; ++ix ) // for loop for each interface + + for( integer ix = 0; ix < 2; ++ix ) // for loop over each half flux { // loop over phases // clear arrays: @@ -1405,9 +1438,9 @@ class FaceBasedAssemblyInterfaceConditionKernel : public FaceBasedAssemblyKernel for( integer ke = 0; ke < 2; ++ke ) { - localIndex const er = seri[ix]; - localIndex const esr = sesri[ix]; - localIndex const ei = sei[ix]; + localIndex const er = seri[ke]; + localIndex const esr = sesri[ke]; + localIndex const ei = sei[ke]; real64 const pressure = m_pres[er][esr][ei]; // P = P1 || P2 presGrad[ip] += transHat[ix] * pressure; // DPv = T (P1 - P2) @@ -1427,7 +1460,7 @@ class FaceBasedAssemblyInterfaceConditionKernel : public FaceBasedAssemblyKernel if( m_hasCapPressure ) // check sign convention { - real64 capPres = m_phaseCapPressure[er][esr][ei][0][ip]; // Pc = Pc1 || Pc2 + real64 capPres = m_phaseCapPressure[seri[ix]][sesri[ix]][sei[ix]][0][ip]; // Pc = Pc1 || Pc2 if( ke == 1 && ix == 0 ) { capPres = faceCapPres1[0][0][ip]; @@ -1456,11 +1489,9 @@ class FaceBasedAssemblyInterfaceConditionKernel : public FaceBasedAssemblyKernel if( ke == 1 && ix == 0 ) { - real64 dCapPresIC_dS = dfacePhaseVolFrac_dCapPres1[0][0][ip][ip]; - dCapPres_dS = 1 / ( dCapPresIC_dS + eps); + dCapPres_dS = dCapPres1_dfacePhaseVolFrac[0][0][ip][ip]; } else if ( ke == 1 && ix == 1 ) { - real64 dCapPresIC_dS = dfacePhaseVolFrac_dCapPres2[0][0][ip][ip]; - dCapPres_dS = 1 / ( dCapPresIC_dS + eps); + dCapPres_dS = dCapPres2_dfacePhaseVolFrac[0][0][ip][ip]; } // dPc2/dS2 dCapGrad_dP[ip][ke] += dTransHat_dP[ix] * dCapGrad_dTrans; // dDPc/dP = { dT/dP1 * @@ -1500,12 +1531,12 @@ class FaceBasedAssemblyInterfaceConditionKernel : public FaceBasedAssemblyKernel if( k_up == 1 && ix == 0 ) { - mobility[ip] = faceRelPerm1[0][ip][ip] * density[ip] / viscosity[ip]; // M = Mupstream - dMob_dP[ip][k_up] = mobility[ip] * (dDens_dP[ip][ip] / density[ip] - dVisc_dP[ip][ip] / viscosity[ip]); // dM/dP = {dM/dP1 , 0} OR {0 , dM/dP2} + mobility[ip] = faceRelPerm1[0][0][ip] * density[ip] / viscosity[ip]; // M = Mupstream + dMob_dP[ip][k_up] = mobility[ip] * (dDens_dP[ip][ix] / density[ip] - dVisc_dP[ip][ix] / viscosity[ip]); // dM/dP = {dM/dP1 , 0} OR {0 , dM/dP2} dMob_dS[ip][k_up] = dfacePhaseRelPerm1_dPhaseVolFrac[0][0][ip][ip] * density[ip] / viscosity[ip]; // dM/dS = {dM/dS1 , 0} OR {0 , dM/dS2} } else if ( k_up == 1 && ix == 1 ) { - mobility[ip] = faceRelPerm2[0][ip][ip] * density[ip] / viscosity[ip]; // M = Mupstream - dMob_dP[ip][k_up] = mobility[ip] * (dDens_dP[ip][ip] / density[ip] - dVisc_dP[ip][ip] / viscosity[ip]); // dM/dP = {dM/dP1 , 0} OR {0 , dM/dP2} + mobility[ip] = faceRelPerm2[0][0][ip] * density[ip] / viscosity[ip]; // M = Mupstream + dMob_dP[ip][k_up] = mobility[ip] * (dDens_dP[ip][ix] / density[ip] - dVisc_dP[ip][ix] / viscosity[ip]); // dM/dP = {dM/dP1 , 0} OR {0 , dM/dP2} dMob_dS[ip][k_up] = dfacePhaseRelPerm2_dPhaseVolFrac[0][0][ip][ip] * density[ip] / viscosity[ip]; // dM/dS = {dM/dS1 , 0} OR {0 , dM/dS2} } else { mobility[ip] = m_mob[seri[k_up]][sesri[k_up]][sei[k_up]][ip]; // M = Mupstream @@ -1539,87 +1570,91 @@ class FaceBasedAssemblyInterfaceConditionKernel : public FaceBasedAssemblyKernel } // loop over phases /// Three Forces Flux Contribution: 1- Viscous 2- Gravitational 3- Capillary + constexpr int sign[2] = {1, -1}; // loop over phases for( integer ip = 0; ip < m_numPhases; ++ip ) { // 1- Viscous: pressure gradient depends on all points in the stencil for( integer ke = 0; ke < 2; ++ke ) { - halfFluxVal[ip][ix] = mobility[ip] / total_mobility * uT; - dhalfFlux_dP[ip][ix + ke] = dPresGrad_dP[ip][ke]; // dF/dP = { T + dT/dP1 * (P1 - P2) , + halfFluxVal[ip][ix] = sign[0] * mobility[ip] / total_mobility * uT; + dhalfFlux_dP[ip][ix + ke] = sign[0] * sign[ip] * (dMob_dP[0][ke] * mobility[0] - dMob_dP[1][ke] * mobility[1]) / (total_mobility * total_mobility) * uT; // dF/dP = { T + dT/dP1 * (P1 - P2) , // -T + dT/dP2 * (P1 - P2) } + dhalfFlux_dS[ip][ix + ke] = sign[0] * sign[ip] * (dMob_dS[0][ke] * mobility[0] - dMob_dS[1][ke] * mobility[1]) / (total_mobility * total_mobility) * uT; + } // 2- Gravitational: gravitational head depends only on the two cells connected (same as mean density) for( integer ke = 0; ke < 2; ++ke ) { halfFluxVal[ip][ix] -= mobility[0] * mobility[1] / total_mobility * gravHead[ip]; - dhalfFlux_dP[ip][ix + ke] -= dGravHead_dP[ip][ke]; // dF/dP = { T + dT/dP1 * (P1 - P2) - drho/dP1 * T g (z1 - z2) - dT/dP1 * rho g (z1 - - // z2) , - // -T + dT/dP2 * (P1 - P2) - drho/dP2 * T g (z1 - z2) - dT/dP2 * rho g (z1 - - // z2) } + + dhalfFlux_dP[ip][ix + ke] -= (dMob_dP[0][ke] * mobility[0] * mobility[0]+ dMob_dP[1][ke] * mobility[1] * mobility[1]) / (total_mobility * total_mobility) * gravHead[ip] + mobility[0] * mobility[1] / total_mobility * dGravHead_dP[ip][ke]; // dF/dP = { T + dT/dP1 * (P1 - P2) , + // -T + dT/dP2 * (P1 - P2) } + dhalfFlux_dS[ip][ix + ke] -= (dMob_dS[0][ke] * mobility[0] * mobility[0]+ dMob_dS[1][ke] * mobility[1] * mobility[1]) / (total_mobility * total_mobility) * gravHead[ip]; } // 3- Capillary: capillary pressure contribution + if( m_hasCapPressure ) { for( integer ke = 0; ke < 2; ++ke ) { - halfFluxVal[ip][ix] += mobility[0] * mobility[1] / total_mobility * capGrad[ip]; - dhalfFlux_dP[ip][ix + ke] += dCapGrad_dP[ip][ke]; // dF/dP = { T + dT/dP1 * (P1 - P2) - drho/dP1 * T g (z1 - z2) - dT/dP1 * rho g (z1 - // - z2) + dT/dP1 * (-Pc1 + Pc2) , - // -T + dT/dP2 * (P1 - P2) - drho/dP2 * T g (z1 - z2) - dT/dP2 * rho g (z1 - // - z2) + dT/dP2 * (-Pc1 + Pc2) } + halfFluxVal[ip][ix] -= sign[ip] * mobility[0] * mobility[1] / total_mobility * capGrad[1]; - dhalfFlux_dS[ip][ix + ke] = dCapGrad_dS[ip][ke]; // dF/dS = { T * -dPc/dS1 , T * dPc/dS2 } + dhalfFlux_dP[ip][ix + ke] -= sign[ip] * (dMob_dP[0][ke] * mobility[0] * mobility[0]+ dMob_dP[1][ke] * mobility[1] * mobility[1]) / (total_mobility * total_mobility) * capGrad[1] + mobility[0] * mobility[1] / total_mobility * dCapGrad_dP[ip][ke]; // dF/dP = { T + dT/dP1 * (P1 - P2) , + // -T + dT/dP2 * (P1 - P2) } + dhalfFlux_dS[ip][ix + ke] -= sign[ip] * (dMob_dP[0][ke] * mobility[0] * mobility[0]+ dMob_dP[1][ke] * mobility[1] * mobility[1]) / (total_mobility * total_mobility) * capGrad[1] + mobility[0] * mobility[1] / total_mobility * dCapGrad_dS[ip][ke]; } } - - for( integer ke = 0; ke < 2; ++ke ) - { - dhalfFlux_dP[ip][ix + ke] *= mobility[ip]; // dF/dP = { M [ T + dT/dP1 * (P1 - P2) - drho/dP1 * T g (z1 - z2) - dT/dP1 * rho g (z1 - - // z2) + dT/dP1 * (-Pc1 + Pc2)] , - // M [-T + dT/dP2 * (P1 - P2) - drho/dP2 * T g (z1 - z2) - dT/dP2 * rho g (z1 - - // z2) + dT/dP2 * (-Pc1 + Pc2)] } - - dhalfFlux_dS[ip][ix + ke] *= mobility[ip]; // dF/dS = { M [T * -dPc/dS1] , M [T * dPc/dS2] } - } - - // add contribution from upstream cell mobility derivatives - for( integer ke = 0; ke < 2; ++ke ) - { - dhalfFlux_dP[ip][ix + ke] += dMob_dP[ip][ke] * potGrad_ip[ip]; // dF/dP = { M [ T + dT/dP1 * (P1 - P2) - drho1/dP * T g (z1 - z2) - dT/dP1 * - // rho g (z1 - z2) + dT/dP1 * (-Pc1 + Pc2)] + dM/dP1 * DPhi , - // M [-T + dT/dP2 * (P1 - P2) - drho2/dP * T g (z1 - z2) - dT/dP2 * - // rho g (z1 - z2) + dT/dP2 * (-Pc1 + Pc2)] + dM/dP2 * DPhi } - dhalfFlux_dS[ip][ix + ke] += dMob_dS[ip][ke] * potGrad_ip[ip]; // dF/dS = { M [T * -dPc/dS1] + dM/dS1 * DPhi , M [T * dPc/dS2] + dM/dS2 * DPhi - // } - } - - // does } // loop over phases } // loop over half fluxes - local_jacobian = dhalfFlux_dS[1][1]*dfacePhaseVolFrac_dCapPres1[0][0][1][1] - dhalfFlux_dS[1][3]*dfacePhaseVolFrac_dCapPres2[0][0][1][1]; - local_residual = halfFluxVal[1][0] - halfFluxVal[1][1]; - + local_jacobian = dhalfFlux_dS[1][1]*dfacePhaseVolFrac_dCapPres1[0][0][1][1] + dhalfFlux_dS[1][3]*dfacePhaseVolFrac_dCapPres2[0][0][1][1]; + local_residual = halfFluxVal[1][0] + halfFluxVal[1][1]; + + // // Write data to the file + // outFile << local_jacobian; + // outFile << ","; + // outFile << local_residual; + // outFile << ","; + // outFile << halfFluxVal[1][0]; + // outFile << ","; + // outFile << halfFluxVal[1][1]; + // outFile << ","; + // outFile << Pc_int; + // outFile << ","; + // outFile << iter; + // outFile << std::endl; + + if (std::fabs(local_jacobian) < 1e-16) { + std::cout << "Derivative is too small" << std::endl; + break; + } + + //std::cout << GEOS_FMT( " phase_mass = ( {:4.2e} )", phase_mass ); real64 deltaPc = local_residual/local_jacobian; + + std::cout << GEOS_FMT( " local_R = ( {:4.2e} )", local_residual ); + std::cout << GEOS_FMT( " deltaPc = ( {:4.2e} )", deltaPc ); + Pc_int -= deltaPc; - iter++; // Check convergence if (std::fabs(local_residual) < tol) { break; // Converged } + iter++; + } // while loop - } - + // // Close the file after writing + // outFile.close(); for( integer ip = 0; ip < m_numPhases; ++ip ) { // populate local flux vector and derivatives @@ -1642,21 +1677,6 @@ class FaceBasedAssemblyInterfaceConditionKernel : public FaceBasedAssemblyKernel // Customize the kernel with this lambda kernelOp( k, seri, sesri, sei, connectionIndex, alpha_ip[ip], mobility, potGrad_ip[ip], fluxVal, dFlux_dP, dFlux_dS ); // Not sure what this - - // } -// // // compute S_alpha and S_beta: - // S_int[0] = computePCalphaInv< arrayView1d< real64 const > >( Pc_int ); - // S_int[1] = computePCalphaInv< arrayView1d< real64 const > >( Pc_int ); - - // real64 S_avg = S_int[0] + S_int[1]; - - // // real64 PC_int1 = computePCalphaInv > ( S_int[0] ); - // // real64 PC_int2 = computePCalphaInv > ( S_int[1] ); - - - - // GEOS_UNUSED_PARAM( Pc_int ); - } // loop over phases } // end of else for interface conditions connectionIndex++; From 7493d2912ef3a4700fa8aac1c1d9ee3df5b29733 Mon Sep 17 00:00:00 2001 From: Randolph Settgast Date: Fri, 10 Oct 2025 16:23:52 -0700 Subject: [PATCH 093/102] feat: data structure for enabling capillary interface conditions (#3657) * enable creation of new FaceElementSubregion entries from interface sets * wip: draft for a working example * wip: parsing registered container "interfaceFaceSetNames" * wip: two-regions example * wip: initializePreSubGroups() is executing * wip: inelegant access to relperms * wip: filling up m_constitutitveFluidModels * wip: apply formatter uncrustify * Update ImmiscibleMultiphaseFlow.cpp * Update ImmiscibleMultiphaseFlow.cpp * Update ImmiscibleMultiphaseFlow.cpp * Update uni_directional_flow_interface_condition.xml * wip: commenting some attributions of addToFractureMesh * wip: split attributions of addToFractureMesh * wip: strongly typed implementation * Update immiscibleTwoPhase_GravitySegregation_1d.xml * wip: remove reference to nonexistent test file * wip: apply formatter uncrustify * added capPressure and fluid to m_constitutitveFluidModels * wip: rename attribute m_constitutitveFluidModels to m_interfaceConstitutivePairs * wip: extending example xml file * Update ImmiscibleMultiphaseFlow.cpp * Update ImmiscibleMultiphaseFlow.cpp * Update SurfaceElementRegion.cpp * refactor: split functionality of addToFractureMesh * Update ImmiscibleMultiphaseKernels.hpp * Update ImmiscibleMultiphaseKernels.hpp * passing m_interfaceFaceSetNames and m_interfaceConstitutivePairs to the FluxComputeKernel * some cleanup * wip: reducing signature of addToSurfaceMesh Co-Authored-By: Randolph Settgast * run formatter uncrusitfy Co-Authored-By: Randolph Settgast Revert "run formatter uncrusitfy" This reverts commit c801af3c526046770fff6460ee07025824e62a2b. run formatter uncrusitfy * wip: using originalFaceToEdgeMap * fix: unused variable 'edgeMap' * Update SurfaceElementRegion.cpp * Update SurfaceElementRegion.cpp * Update SurfaceElementRegion.cpp * Update SurfaceElementRegion.hpp * Update ImmiscibleMultiphaseFlow.cpp * wip: adding a index map between interfaceRegion and its associated "Connectors" * Update StencilBase.hpp * Update StencilBase.hpp * Update ImmiscibleMultiphaseFlow.cpp * wip: Simplify implementation * wip: uncrustify style * wip: remove geos scope * Update ImmiscibleMultiphaseKernels.hpp * Update ImmiscibleMultiphaseKernels.hpp * Update ImmiscibleMultiphaseFlow.cpp * debugged and working local solver for the interface conditions that converges for viscous, gravity, and capillary fluxes * Update StencilBase.hpp * Update ImmiscibleMultiphaseFlow.hpp Introducing an alternative container m_connectorIndicesByInterfaceRegion this implies call the nonlinear interface solver in a separate call * WIP: adding some extra comments * wip: fix indentation * Adding an example input file * refactor: clean up files * Update ImmiscibleMultiphaseKernels.hpp * Update ImmiscibleMultiphaseKernels.hpp * Moved the local solver to be an inline static function * change interfaceConstitutivePairs type from ConstitutiveBase to each model's type Base * added a unit Test for the local interface conditions solver and resolved some merge conflicts * adding unitTest --------- Co-authored-by: Omar Duran Co-authored-by: Ammara-14 --- ...miscibleTwoPhase_GravitySegregation_1d.xml | 2 +- ...oPhase_GravitySegregation_1d_pc_heter2.xml | 280 ++ .../initialPressure.txt | 10 + .../initialSaturation1.txt | 10 + .../initialSaturation2.txt | 10 + .../jFunction_linear.txt | 2 + .../permx.geos | 10 + .../permy.geos | 10 + .../permz.geos | 10 + .../phaseVolumeFraction_water_linear.txt | 2 + .../tables/jFunction.txt | 13 + .../tables/jFunction_linear.txt | 2 + .../tables/phaseVolumeFraction_water.txt | 13 + .../phaseVolumeFraction_water_linear.txt | 2 + .../x.txt | 1 + .../y.txt | 1 + .../z.txt | 10 + .../tables/jFunction_linear.txt | 2 + .../tables/phaseVolumeFraction_water.txt | 76 + .../phaseVolumeFraction_water_linear.txt | 2 + .../uni_directional_flow_base.xml | 225 ++ ...i_directional_flow_interface_condition.xml | 66 + .../BrooksCoreyCapillaryPressure.hpp | 174 +- .../CapillaryPressureSelector.hpp | 24 +- .../JFunctionCapillaryPressure.cpp | 39 +- .../JFunctionCapillaryPressure.hpp | 34 +- .../TableCapillaryPressure.cpp | 48 +- .../TableCapillaryPressure.hpp | 35 +- .../VanGenuchtenCapillaryPressure.hpp | 68 + .../unitTests/FluidModelTest_impl.hpp | 2 +- .../finiteVolume/CellElementStencilTPFA.hpp | 36 +- .../EmbeddedSurfaceToCellStencil.hpp | 16 +- .../finiteVolume/FaceElementToCellStencil.hpp | 30 +- .../finiteVolume/SurfaceElementStencil.hpp | 16 +- .../testImmiscibleInterfaceConditions.cpp | 677 +++++ .../wellsTests/CMakeLists.txt | 17 + .../fluidFlow/ImmiscibleMultiphaseFlow.cpp | 91 +- .../fluidFlow/ImmiscibleMultiphaseFlow.hpp | 25 +- .../ImmiscibleMultiphaseKernels.hpp | 2453 ++++++++++++----- 39 files changed, 3636 insertions(+), 908 deletions(-) create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/immiscibleTwoPhase_GravitySegregation_1d_pc_heter2.xml create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/initialPressure.txt create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/initialSaturation1.txt create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/initialSaturation2.txt create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/jFunction_linear.txt create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/permx.geos create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/permy.geos create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/permz.geos create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/phaseVolumeFraction_water_linear.txt create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/tables/jFunction.txt create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/tables/jFunction_linear.txt create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/tables/phaseVolumeFraction_water.txt create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/tables/phaseVolumeFraction_water_linear.txt create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/x.txt create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/y.txt create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/z.txt create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/tables/jFunction_linear.txt create mode 100755 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/tables/phaseVolumeFraction_water.txt create mode 100755 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/tables/phaseVolumeFraction_water_linear.txt create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/uni_directional_flow_base.xml create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/uni_directional_flow_interface_condition.xml create mode 100644 src/coreComponents/integrationTests/fluidFlowTests/testImmiscibleInterfaceConditions.cpp diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_GravitySegregation_1d/immiscibleTwoPhase_GravitySegregation_1d.xml b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_GravitySegregation_1d/immiscibleTwoPhase_GravitySegregation_1d.xml index 12e6d52f990..62d4f6cf3bb 100644 --- a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_GravitySegregation_1d/immiscibleTwoPhase_GravitySegregation_1d.xml +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_GravitySegregation_1d/immiscibleTwoPhase_GravitySegregation_1d.xml @@ -115,7 +115,7 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/initialPressure.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/initialPressure.txt new file mode 100644 index 00000000000..63943bfa00d --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/initialPressure.txt @@ -0,0 +1,10 @@ +1e7 +1e7 +1e7 +1e7 +1e7 +1e7 +1e7 +1e7 +1e7 +1e7 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/initialSaturation1.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/initialSaturation1.txt new file mode 100644 index 00000000000..79cccb86897 --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/initialSaturation1.txt @@ -0,0 +1,10 @@ +0.4 +0.4 +0.8 +0.8 +0.8 +0.8 +0.8 +0.8 +0.8 +0.8 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/initialSaturation2.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/initialSaturation2.txt new file mode 100644 index 00000000000..72c544974fe --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/initialSaturation2.txt @@ -0,0 +1,10 @@ +0.6 +0.6 +0.2 +0.2 +0.2 +0.2 +0.2 +0.2 +0.2 +0.2 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/jFunction_linear.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/jFunction_linear.txt new file mode 100644 index 00000000000..c3dfd50073f --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/jFunction_linear.txt @@ -0,0 +1,2 @@ +4.33172935918785 +1.66604975353379 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/permx.geos b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/permx.geos new file mode 100644 index 00000000000..ec8beb6c503 --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/permx.geos @@ -0,0 +1,10 @@ +112.5 +112.5 +112.5 +112.5 +112.5 +50 +50 +50 +50 +50 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/permy.geos b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/permy.geos new file mode 100644 index 00000000000..ec8beb6c503 --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/permy.geos @@ -0,0 +1,10 @@ +112.5 +112.5 +112.5 +112.5 +112.5 +50 +50 +50 +50 +50 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/permz.geos b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/permz.geos new file mode 100644 index 00000000000..ec8beb6c503 --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/permz.geos @@ -0,0 +1,10 @@ +112.5 +112.5 +112.5 +112.5 +112.5 +50 +50 +50 +50 +50 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/phaseVolumeFraction_water_linear.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/phaseVolumeFraction_water_linear.txt new file mode 100644 index 00000000000..0d66ea1aee9 --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/phaseVolumeFraction_water_linear.txt @@ -0,0 +1,2 @@ +0 +1 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/tables/jFunction.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/tables/jFunction.txt new file mode 100644 index 00000000000..dfd48c60a6b --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/tables/jFunction.txt @@ -0,0 +1,13 @@ +4.331729359 +3.523266264 +2.677103439 +2.356150157 +2.166062360 +2.034158727 +1.934627222 +1.855494313 +1.790286970 +1.735134860 +1.687551617 +1.666049754 + diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/tables/jFunction_linear.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/tables/jFunction_linear.txt new file mode 100644 index 00000000000..13036f8fd03 --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/tables/jFunction_linear.txt @@ -0,0 +1,2 @@ +100.00 +1.00 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/tables/phaseVolumeFraction_water.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/tables/phaseVolumeFraction_water.txt new file mode 100644 index 00000000000..4c7e1f01e40 --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/tables/phaseVolumeFraction_water.txt @@ -0,0 +1,13 @@ +0 +0.05 +0.15 +0.25 +0.35 +0.45 +0.55 +0.65 +0.75 +0.85 +0.95 +1 + diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/tables/phaseVolumeFraction_water_linear.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/tables/phaseVolumeFraction_water_linear.txt new file mode 100644 index 00000000000..0a269ee3741 --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/tables/phaseVolumeFraction_water_linear.txt @@ -0,0 +1,2 @@ +0.0 +1.0 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/x.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/x.txt new file mode 100644 index 00000000000..7ed6ff82de6 --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/x.txt @@ -0,0 +1 @@ +5 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/y.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/y.txt new file mode 100644 index 00000000000..7ed6ff82de6 --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/y.txt @@ -0,0 +1 @@ +5 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/z.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/z.txt new file mode 100644 index 00000000000..d71cc528224 --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/z.txt @@ -0,0 +1,10 @@ +5 +15 +25 +35 +45 +55 +65 +75 +85 +95 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/tables/jFunction_linear.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/tables/jFunction_linear.txt new file mode 100644 index 00000000000..c2cba8f9783 --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/tables/jFunction_linear.txt @@ -0,0 +1,2 @@ +10000 +3000 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/tables/phaseVolumeFraction_water.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/tables/phaseVolumeFraction_water.txt new file mode 100755 index 00000000000..30a57a9dee4 --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/tables/phaseVolumeFraction_water.txt @@ -0,0 +1,76 @@ +0 +0.013333333 +0.026666667 +0.04 +0.053333333 +0.066666667 +0.08 +0.093333333 +0.106666667 +0.12 +0.133333333 +0.146666667 +0.16 +0.173333333 +0.186666667 +0.2 +0.213333333 +0.226666667 +0.24 +0.253333333 +0.266666667 +0.28 +0.293333333 +0.306666667 +0.32 +0.333333333 +0.346666667 +0.36 +0.373333333 +0.386666667 +0.4 +0.413333333 +0.426666667 +0.44 +0.453333333 +0.466666667 +0.48 +0.493333333 +0.506666667 +0.52 +0.533333333 +0.546666667 +0.56 +0.573333333 +0.586666667 +0.6 +0.613333333 +0.626666667 +0.64 +0.653333333 +0.666666667 +0.68 +0.693333333 +0.706666667 +0.72 +0.733333333 +0.746666667 +0.76 +0.773333333 +0.786666667 +0.8 +0.813333333 +0.826666667 +0.84 +0.853333333 +0.866666667 +0.88 +0.893333333 +0.906666667 +0.92 +0.933333333 +0.946666667 +0.96 +0.973333333 +0.986666667 +1 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/tables/phaseVolumeFraction_water_linear.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/tables/phaseVolumeFraction_water_linear.txt new file mode 100755 index 00000000000..0d66ea1aee9 --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/tables/phaseVolumeFraction_water_linear.txt @@ -0,0 +1,2 @@ +0 +1 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/uni_directional_flow_base.xml b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/uni_directional_flow_base.xml new file mode 100644 index 00000000000..2640edbdc80 --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/uni_directional_flow_base.xml @@ -0,0 +1,225 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/uni_directional_flow_interface_condition.xml b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/uni_directional_flow_interface_condition.xml new file mode 100644 index 00000000000..c263012d27c --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/uni_directional_flow_interface_condition.xml @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/coreComponents/constitutive/capillaryPressure/BrooksCoreyCapillaryPressure.hpp b/src/coreComponents/constitutive/capillaryPressure/BrooksCoreyCapillaryPressure.hpp index c020174dd21..6b9972253d7 100644 --- a/src/coreComponents/constitutive/capillaryPressure/BrooksCoreyCapillaryPressure.hpp +++ b/src/coreComponents/constitutive/capillaryPressure/BrooksCoreyCapillaryPressure.hpp @@ -57,6 +57,11 @@ class BrooksCoreyCapillaryPressureUpdate final : public CapillaryPressureBaseUpd arraySlice1d< real64, cappres::USD_CAPPRES - 2 > const & phaseCapPres, arraySlice2d< real64, cappres::USD_CAPPRES_DS - 2 > const & dPhaseCapPres_dPhaseVolFrac ) const; + GEOS_HOST_DEVICE + void computeInv( arraySlice1d< real64, compflow::USD_PHASE - 1 > const & phaseVolFraction, + arraySlice1d< real64 const, cappres::USD_CAPPRES - 2 > const & phaseCapPres, + arraySlice2d< real64, cappres::USD_CAPPRES_DS - 2 > const & dPhaseCapPres_dPhaseVolFrac ) const; + GEOS_HOST_DEVICE virtual void update( localIndex const k, localIndex const q, @@ -80,14 +85,35 @@ class BrooksCoreyCapillaryPressureUpdate final : public CapillaryPressureBaseUpd real64 & phaseCapPressure, real64 & dPhaseCapPressure_dVolFrac ); + +GEOS_HOST_DEVICE +GEOS_FORCE_INLINE +static void +evaluateBrooksCoreyFunctionInv( real64 const phaseCapPressure, + int const ip, + real64 const volFracScaleInv, + real64 const exponentInv, + real64 const entryPressure, + real64 const maxCapPres_eps, + real64 const phaseMinVolumeFraction, + arrayView1d< integer const > const phaseOrder, + real64 & phaseVolFraction, + real64 & dPhaseCapPressure_dVolFrac ); + arrayView1d< real64 const > m_phaseMinVolumeFraction; arrayView1d< real64 const > m_phaseCapPressureExponentInv; arrayView1d< real64 const > m_phaseEntryPressure; real64 m_capPressureEpsilon; real64 m_volFracScale; + }; + + + + + class BrooksCoreyCapillaryPressure : public CapillaryPressureBase { public: @@ -171,11 +197,12 @@ BrooksCoreyCapillaryPressureUpdate:: // compute first gas-oil capillary pressure as a function of gas-phase vol fraction integer const ip_gas = m_phaseOrder[CapillaryPressureBase::PhaseType::GAS]; - if( ip_gas >= 0 ) + integer const ip_oil = m_phaseOrder[CapillaryPressureBase::PhaseType::OIL]; + if( ip_oil >= 0 ) { - real64 const volFracScaled = (phaseVolFraction[ip_gas] - m_phaseMinVolumeFraction[ip_gas]) * volFracScaleInv; - real64 const exponentInv = m_phaseCapPressureExponentInv[ip_gas]; - real64 const entryPressure = -m_phaseEntryPressure[ip_gas]; // for gas capillary pressure, take the opposite of the + real64 const volFracScaled = (phaseVolFraction[ip_oil] - m_phaseMinVolumeFraction[ip_oil]) * volFracScaleInv; + real64 const exponentInv = m_phaseCapPressureExponentInv[ip_oil]; + real64 const entryPressure = -m_phaseEntryPressure[ip_oil]; // for gas capillary pressure, take the opposite of the // BC function real64 const wettingVolFracScaled = 1-volFracScaled; @@ -186,9 +213,101 @@ BrooksCoreyCapillaryPressureUpdate:: exponentInv, entryPressure, eps, - phaseCapPres[ip_gas], - dPhaseCapPres_dPhaseVolFrac[ip_gas][ip_gas] ); + phaseCapPres[ip_oil], + dPhaseCapPres_dPhaseVolFrac[ip_oil][ip_oil] ); + } +} + +GEOS_HOST_DEVICE +inline void +BrooksCoreyCapillaryPressureUpdate:: + computeInv( arraySlice1d< real64, compflow::USD_PHASE - 1 > const & phaseVolFraction, + arraySlice1d< real64 const, cappres::USD_CAPPRES - 2 > const & phaseCapPres, + arraySlice2d< real64, cappres::USD_CAPPRES_DS - 2 > const & dPhaseCapPres_dPhaseVolFrac ) const +{ + LvArray::forValuesInSlice( dPhaseCapPres_dPhaseVolFrac, []( real64 & val ){ val = 0.0; } ); + + real64 const volFracScaleInv = 1.0 / m_volFracScale; + + // the Brooks-Corey model does not support volFracScaled = 0, + // hence we need an epsilon value to avoid a division by zero + // TODO: for S < epsilon, replace the original unbounded BC curve with a bounded power-law extension + real64 const eps = m_capPressureEpsilon; + + + // compute first water-oil capillary pressure as a function of water-phase vol fraction + integer const ip_water = m_phaseOrder[CapillaryPressureBase::PhaseType::WATER]; + integer const ip_gas = m_phaseOrder[CapillaryPressureBase::PhaseType::GAS]; + if( ip_water >= 0 ) + { + real64 const volFracScaled_eps = (eps - m_phaseMinVolumeFraction[ip_water]) * volFracScaleInv; + real64 const exponentInv = m_phaseCapPressureExponentInv[ip_water]; + real64 const entryPressure = m_phaseEntryPressure[ip_water]; + + real64 const wettingVolFracScaled_eps = volFracScaled_eps; + real64 const dWettingVolFracScaled_dVolFrac = volFracScaleInv; + + real64 maxCapPres_eps = 0.0; + real64 max_dpc_eps = 0.0; + + evaluateBrooksCoreyFunction( wettingVolFracScaled_eps, + dWettingVolFracScaled_dVolFrac, + exponentInv, + entryPressure, + eps, + maxCapPres_eps, + max_dpc_eps ); + + evaluateBrooksCoreyFunctionInv( phaseCapPres[ip_water], + ip_water, + volFracScaleInv, + exponentInv, + entryPressure, + maxCapPres_eps, + m_phaseMinVolumeFraction[ip_water], + m_phaseOrder, + phaseVolFraction[ip_water], + dPhaseCapPres_dPhaseVolFrac[ip_water][ip_water] ); + phaseVolFraction[ip_gas] = 1.0 - phaseVolFraction[ip_water]; } + + + // compute first gas-oil capillary pressure as a function of gas-phase vol fraction + + + // if( ip_gas >= 0 ) + // { + // real64 const volFracScaled_eps = (eps - m_phaseMinVolumeFraction[ip_gas]) * volFracScaleInv; + // real64 const exponentInv = m_phaseCapPressureExponentInv[ip_gas]; + // real64 const entryPressure = -m_phaseEntryPressure[ip_gas]; // for gas capillary pressure, take the opposite of the + // // BC function + + // real64 const wettingVolFracScaled_eps = 1-volFracScaled_eps; + // real64 const dWettingVolFracScaled_dVolFrac = -volFracScaleInv; + + // real64 maxCapPres_eps = 0.0; + // real64 max_dpc_eps = 0.0; + + // evaluateBrooksCoreyFunction( wettingVolFracScaled_eps, + // dWettingVolFracScaled_dVolFrac, + // exponentInv, + // entryPressure, + // eps, + // maxCapPres_eps, + // max_dpc_eps ); + + // evaluateBrooksCoreyFunctionInv( phaseCapPres[ip_gas], + // ip_gas, + // volFracScaleInv, + // exponentInv, + // entryPressure, + // maxCapPres_eps, + // m_phaseMinVolumeFraction[ip_gas], + // m_phaseOrder, + // phaseVolFraction[ip_gas], + // dPhaseCapPres_dPhaseVolFrac[ip_gas][ip_gas] ); + // phaseVolFraction[ip_water] = 1.0 - phaseVolFraction[ip_gas]; + // } } GEOS_HOST_DEVICE @@ -224,6 +343,49 @@ BrooksCoreyCapillaryPressureUpdate:: } +GEOS_HOST_DEVICE +inline void +BrooksCoreyCapillaryPressureUpdate:: + evaluateBrooksCoreyFunctionInv( real64 const phaseCapPressure, + int const ip, + real64 const volFracScaleInv, + real64 const exponentInv, + real64 const entryPressure, + real64 const maxCapPres_eps, + real64 const phaseMinVolumeFraction, + arrayView1d< integer const > const phaseOrder, + real64 & phaseVolFraction, + real64 & dPhaseCapPressure_dVolFrac ) +{ + + + phaseVolFraction = 0.0; + real64 value = 0.0; + dPhaseCapPressure_dVolFrac = 0.0; + integer const ip_oil = phaseOrder[CapillaryPressureBase::PhaseType::OIL]; + + real64 const dScaledWettingPhaseVolFrac_dVolFrac = (ip == ip_oil) + ? -volFracScaleInv : volFracScaleInv; + + if( phaseCapPressure <= maxCapPres_eps && phaseCapPressure >= entryPressure ) + { + // intermediate value + real64 const val = pow( entryPressure, exponentInv) / pow( phaseCapPressure , exponentInv + 1 ); + + value = (phaseCapPressure * val) * volFracScaleInv + phaseMinVolumeFraction; // entryPressure * (S_w)^( - 1 / exponentInv ) + dPhaseCapPressure_dVolFrac = -dScaledWettingPhaseVolFrac_dVolFrac * val * exponentInv; + phaseVolFraction = (ip == ip_oil) ? 1.0 - value : value; + } + else // enforce a constant and bounded capillary pressure + { + real64 const val = (phaseCapPressure > maxCapPres_eps) + ? pow( entryPressure, exponentInv) / pow( maxCapPres_eps , exponentInv) : 1.0; + value = val * volFracScaleInv + phaseMinVolumeFraction; + phaseVolFraction = (ip == ip_oil) ? 1.0 - value : value; + } + +} + } // namespace constitutive diff --git a/src/coreComponents/constitutive/capillaryPressure/CapillaryPressureSelector.hpp b/src/coreComponents/constitutive/capillaryPressure/CapillaryPressureSelector.hpp index 90c362850b6..c9b96e018b7 100644 --- a/src/coreComponents/constitutive/capillaryPressure/CapillaryPressureSelector.hpp +++ b/src/coreComponents/constitutive/capillaryPressure/CapillaryPressureSelector.hpp @@ -36,24 +36,24 @@ template< typename LAMBDA > void constitutiveUpdatePassThru( CapillaryPressureBase const & capPres, LAMBDA && lambda ) { - ConstitutivePassThruHandler< - BrooksCoreyCapillaryPressure, - JFunctionCapillaryPressure, - TableCapillaryPressure, - VanGenuchtenCapillaryPressure - >::execute( capPres, std::forward< LAMBDA >( lambda ) ); + ConstitutivePassThruHandler< + BrooksCoreyCapillaryPressure, + JFunctionCapillaryPressure, + TableCapillaryPressure, + VanGenuchtenCapillaryPressure + >::execute( capPres, std::forward< LAMBDA >( lambda ) ); } template< typename LAMBDA > void constitutiveUpdatePassThru( CapillaryPressureBase & capPres, LAMBDA && lambda ) { - ConstitutivePassThruHandler< - BrooksCoreyCapillaryPressure, - JFunctionCapillaryPressure, - TableCapillaryPressure, - VanGenuchtenCapillaryPressure - >::execute( capPres, std::forward< LAMBDA >( lambda ) ); + ConstitutivePassThruHandler< + BrooksCoreyCapillaryPressure, + JFunctionCapillaryPressure, + TableCapillaryPressure, + VanGenuchtenCapillaryPressure + >::execute( capPres, std::forward< LAMBDA >( lambda ) ); } } // namespace constitutive diff --git a/src/coreComponents/constitutive/capillaryPressure/JFunctionCapillaryPressure.cpp b/src/coreComponents/constitutive/capillaryPressure/JFunctionCapillaryPressure.cpp index 687aff531cb..738efb7b77f 100644 --- a/src/coreComponents/constitutive/capillaryPressure/JFunctionCapillaryPressure.cpp +++ b/src/coreComponents/constitutive/capillaryPressure/JFunctionCapillaryPressure.cpp @@ -120,10 +120,11 @@ JFunctionCapillaryPressure::JFunctionCapillaryPressure( std::string const & name registerWrapper( viewKeyStruct::jFunctionWrappersString(), &m_jFuncKernelWrappers ). setSizedFromParent( 0 ). setRestartFlags( RestartFlags::NO_WRITE ); - + registerWrapper( viewKeyStruct::inverseJFunctionWrappersString(), &m_inverseJFuncKernelWrappers ). setSizedFromParent( 0 ). setRestartFlags( RestartFlags::NO_WRITE ); + } void JFunctionCapillaryPressure::postInputInitialization() @@ -315,36 +316,36 @@ void JFunctionCapillaryPressure::createAllTableKernelWrappers() auto const & satArrayView = jFuncTable.getCoordinates()[0]; auto const & jArrayView = jFuncTable.getValues(); - std::vector satVec( satArrayView.size() ); - std::vector jVec( jArrayView.size() ); + std::vector< real64 > satVec( satArrayView.size() ); + std::vector< real64 > jVec( jArrayView.size() ); std::copy( satArrayView.begin(), satArrayView.end(), satVec.begin() ); std::copy( jArrayView.begin(), jArrayView.end(), jVec.begin() ); // Reverse both arrays (if original J is decreasing in S) -std::reverse( jVec.begin(), jVec.end() ); -std::reverse( satVec.begin(), satVec.end() ); + std::reverse( jVec.begin(), jVec.end() ); + std::reverse( satVec.begin(), satVec.end() ); + - -auto inverseTable = std::make_shared( "inverseJFunc", this ); + auto inverseTable = std::make_shared< TableFunction >( "inverseJFunc", this ); -real64_array invJVec( jVec.size() ); -real64_array invSatVec( satVec.size() ); -std::copy( jVec.begin(), jVec.end(), invJVec.data() ); -std::copy( satVec.begin(), satVec.end(), invSatVec.data() ); + real64_array invJVec( jVec.size() ); + real64_array invSatVec( satVec.size() ); + std::copy( jVec.begin(), jVec.end(), invJVec.data() ); + std::copy( satVec.begin(), satVec.end(), invSatVec.data() ); -array1d< real64_array > coordinates; -coordinates.emplace_back( std::move( invJVec ) ); + array1d< real64_array > coordinates; + coordinates.emplace_back( std::move( invJVec ) ); -std::vector< units::Unit > dimUnits = { units::Unknown }; // or actual unit if available + std::vector< units::Unit > dimUnits = { units::Unknown }; // or actual unit if available -inverseTable->setTableCoordinates( coordinates, dimUnits ); -inverseTable->setTableValues( std::move( invSatVec ), units::Unknown ); -inverseTable->setInterpolationMethod( TableFunction::InterpolationType::Linear ); + inverseTable->setTableCoordinates( coordinates, dimUnits ); + inverseTable->setTableValues( std::move( invSatVec ), units::Unknown ); + inverseTable->setInterpolationMethod( TableFunction::InterpolationType::Linear ); -m_inverseJFuncKernelWrappers.emplace_back( inverseTable->createKernelWrapper() ); -m_inverseTables.emplace_back( std::move( inverseTable ) ); + m_inverseJFuncKernelWrappers.emplace_back( inverseTable->createKernelWrapper() ); + m_inverseTables.emplace_back( std::move( inverseTable ) ); } else if( numPhases == 3 ) diff --git a/src/coreComponents/constitutive/capillaryPressure/JFunctionCapillaryPressure.hpp b/src/coreComponents/constitutive/capillaryPressure/JFunctionCapillaryPressure.hpp index 89bb6e7ef2c..80815e98236 100644 --- a/src/coreComponents/constitutive/capillaryPressure/JFunctionCapillaryPressure.hpp +++ b/src/coreComponents/constitutive/capillaryPressure/JFunctionCapillaryPressure.hpp @@ -82,7 +82,7 @@ class JFunctionCapillaryPressure : public CapillaryPressureBase void computeInv( arraySlice1d< real64, compflow::USD_PHASE - 1 > const & phaseVolFraction, arraySlice1d< real64 const > const & jFuncMultiplier, arraySlice1d< real64 const, cappres::USD_CAPPRES - 2 > const & phaseCapPres, - arraySlice2d< real64, cappres::USD_CAPPRES_DS - 2 > const & dPhaseCapPres_dPhaseVolFrac ) const; + arraySlice2d< real64, cappres::USD_CAPPRES_DS - 2 > const & dPhaseCapPres_dPhaseVolFrac ) const; GEOS_HOST_DEVICE @@ -181,7 +181,7 @@ class JFunctionCapillaryPressure : public CapillaryPressureBase array1d< TableFunction::KernelWrapper > m_jFuncKernelWrappers; array1d< TableFunction::KernelWrapper > m_inverseJFuncKernelWrappers; - std::vector< std::shared_ptr > m_inverseTables; + std::vector< std::shared_ptr< TableFunction > > m_inverseTables; }; @@ -260,9 +260,9 @@ GEOS_HOST_DEVICE inline void JFunctionCapillaryPressure::KernelWrapper:: computeInv( arraySlice1d< real64, compflow::USD_PHASE - 1 > const & phaseVolFraction, - arraySlice1d< real64 const > const & jFuncMultiplier, - arraySlice1d< real64 const, cappres::USD_CAPPRES - 2 > const & phaseCapPres, - arraySlice2d< real64, cappres::USD_CAPPRES_DS - 2 > const & dPhaseCapPres_dPhaseVolFrac ) const + arraySlice1d< real64 const > const & jFuncMultiplier, + arraySlice1d< real64 const, cappres::USD_CAPPRES - 2 > const & phaseCapPres, + arraySlice2d< real64, cappres::USD_CAPPRES_DS - 2 > const & dPhaseCapPres_dPhaseVolFrac ) const { LvArray::forValuesInSlice( dPhaseCapPres_dPhaseVolFrac, []( real64 & val ){ val = 0.0; } ); @@ -271,24 +271,24 @@ JFunctionCapillaryPressure::KernelWrapper:: integer const ipOil = m_phaseOrder[PT::OIL]; integer const ipGas = m_phaseOrder[PT::GAS]; - // apply multiplier + // apply multiplier real64 capPresWater_J = phaseCapPres[ipWater] / jFuncMultiplier[0]; - // std::cout << GEOS_FMT( " JM_2 = ( {:4.2e} )", jFuncMultiplier[0] ); - array1d input(1); + // std::cout << GEOS_FMT( " JM_2 = ( {:4.2e} )", jFuncMultiplier[0] ); + array1d< real64 > input( 1 ); input[0] = capPresWater_J; - // std::cout << GEOS_FMT( " J_int2 = ( {:4.2e} )", input[0] ); - // std::cout << GEOS_FMT( " Pc_int2 = ( {:4.2e} )", phaseCapPres[ipWater] ); + // std::cout << GEOS_FMT( " J_int2 = ( {:4.2e} )", input[0] ); + // std::cout << GEOS_FMT( " Pc_int2 = ( {:4.2e} )", phaseCapPres[ipWater] ); auto inputSlice = input.toSliceConst(); - phaseVolFraction[ipWater] = - m_inverseJFuncKernelWrappers[0].compute( inputSlice, - &(dPhaseCapPres_dPhaseVolFrac)[ipWater][ipWater] ); - dPhaseCapPres_dPhaseVolFrac[ipWater][ipWater] /= jFuncMultiplier[0]; - // std::cout << GEOS_FMT( " S_int2 = ( {:4.2e} )", phaseVolFraction[ipWater] ); - // std::cout << GEOS_FMT( " dS/dP = ( {:4.2e} )", dPhaseCapPres_dPhaseVolFrac[ipWater][ipWater] ); - phaseVolFraction[ipGas] = 1.0 - phaseVolFraction[ipWater]; + phaseVolFraction[ipWater] = + m_inverseJFuncKernelWrappers[0].compute( inputSlice, + &(dPhaseCapPres_dPhaseVolFrac)[ipWater][ipWater] ); + dPhaseCapPres_dPhaseVolFrac[ipWater][ipWater] /= jFuncMultiplier[0]; + // std::cout << GEOS_FMT( " S_int2 = ( {:4.2e} )", phaseVolFraction[ipWater] ); + // std::cout << GEOS_FMT( " dS/dP = ( {:4.2e} )", dPhaseCapPres_dPhaseVolFrac[ipWater][ipWater] ); + phaseVolFraction[ipGas] = 1.0 - phaseVolFraction[ipWater]; } GEOS_HOST_DEVICE diff --git a/src/coreComponents/constitutive/capillaryPressure/TableCapillaryPressure.cpp b/src/coreComponents/constitutive/capillaryPressure/TableCapillaryPressure.cpp index 2304238b540..0471bacb6a8 100644 --- a/src/coreComponents/constitutive/capillaryPressure/TableCapillaryPressure.cpp +++ b/src/coreComponents/constitutive/capillaryPressure/TableCapillaryPressure.cpp @@ -66,6 +66,10 @@ TableCapillaryPressure::TableCapillaryPressure( std::string const & name, registerWrapper( viewKeyStruct::capPresWrappersString(), &m_capPresKernelWrappers ). setSizedFromParent( 0 ). setRestartFlags( RestartFlags::NO_WRITE ); + + registerWrapper( viewKeyStruct::inverseCapPresWrappersString(), &m_inverseCapPresWrappers ). + setSizedFromParent( 0 ). + setRestartFlags( RestartFlags::NO_WRITE ); } void TableCapillaryPressure::postInputInitialization() @@ -148,23 +152,63 @@ void TableCapillaryPressure::createAllTableKernelWrappers() // we want to make sure that the wrappers are always up-to-date, so we recreate them everytime m_capPresKernelWrappers.clear(); + m_inverseCapPresWrappers.clear(); + if( numPhases == 2 ) { TableFunction const & capPresTable = functionManager.getGroup< TableFunction >( m_wettingNonWettingCapPresTableName ); m_capPresKernelWrappers.emplace_back( capPresTable.createKernelWrapper() ); + + auto const & satArrayView = capPresTable.getCoordinates()[0]; + auto const & capPresArrayView = capPresTable.getValues(); + + std::vector< real64 > satVec( satArrayView.size() ); + std::vector< real64 > pcVec( capPresArrayView.size() ); + + std::copy( satArrayView.begin(), satArrayView.end(), satVec.begin() ); + std::copy( capPresArrayView.begin(), capPresArrayView.end(), pcVec.begin() ); + + // Reverse both arrays (if original J is decreasing in S) + std::reverse( pcVec.begin(), pcVec.end() ); + std::reverse( satVec.begin(), satVec.end() ); + + + auto inverseTable = std::make_shared< TableFunction >( "inverseJFunc", this ); + + real64_array invPcVec( pcVec.size() ); + real64_array invSatVec( satVec.size() ); + std::copy( pcVec.begin(), pcVec.end(), invPcVec.data() ); + std::copy( satVec.begin(), satVec.end(), invSatVec.data() ); + + array1d< real64_array > coordinates; + coordinates.emplace_back( std::move( invPcVec ) ); + + + std::vector< units::Unit > dimUnits = { units::Unknown }; // or actual unit if available + + inverseTable->setTableCoordinates( coordinates, dimUnits ); + inverseTable->setTableValues( std::move( invSatVec ), units::Unknown ); + inverseTable->setInterpolationMethod( TableFunction::InterpolationType::Linear ); + + m_inverseCapPresWrappers.emplace_back( inverseTable->createKernelWrapper() ); + m_inverseTables.emplace_back( std::move( inverseTable ) ); + } else if( numPhases == 3 ) { TableFunction const & capPresTableWI = functionManager.getGroup< TableFunction >( m_wettingIntermediateCapPresTableName ); m_capPresKernelWrappers.emplace_back( capPresTableWI.createKernelWrapper() ); + m_inverseCapPresWrappers.emplace_back( capPresTableWI.createKernelWrapper() ); TableFunction const & capPresTableNWI = functionManager.getGroup< TableFunction >( m_nonWettingIntermediateCapPresTableName ); m_capPresKernelWrappers.emplace_back( capPresTableNWI.createKernelWrapper() ); + m_inverseCapPresWrappers.emplace_back( capPresTableNWI.createKernelWrapper() ); } } TableCapillaryPressure::KernelWrapper:: KernelWrapper( arrayView1d< TableFunction::KernelWrapper const > const & capPresKernelWrappers, + arrayView1d< TableFunction::KernelWrapper const > const & inverseCapPresWrappers, arrayView1d< integer const > const & phaseTypes, arrayView1d< integer const > const & phaseOrder, arrayView3d< real64, cappres::USD_CAPPRES > const & phaseCapPres, @@ -173,7 +217,8 @@ TableCapillaryPressure::KernelWrapper:: phaseOrder, phaseCapPres, dPhaseCapPres_dPhaseVolFrac ), - m_capPresKernelWrappers( capPresKernelWrappers ) + m_capPresKernelWrappers( capPresKernelWrappers ), + m_inverseCapPresWrappers( inverseCapPresWrappers ) {} TableCapillaryPressure::KernelWrapper @@ -181,6 +226,7 @@ TableCapillaryPressure::createKernelWrapper() { createAllTableKernelWrappers(); return KernelWrapper( m_capPresKernelWrappers, + m_inverseCapPresWrappers, m_phaseTypes, m_phaseOrder, m_phaseCapPressure, diff --git a/src/coreComponents/constitutive/capillaryPressure/TableCapillaryPressure.hpp b/src/coreComponents/constitutive/capillaryPressure/TableCapillaryPressure.hpp index 602946c55de..949d431792a 100644 --- a/src/coreComponents/constitutive/capillaryPressure/TableCapillaryPressure.hpp +++ b/src/coreComponents/constitutive/capillaryPressure/TableCapillaryPressure.hpp @@ -55,6 +55,7 @@ class TableCapillaryPressure : public CapillaryPressureBase public: KernelWrapper( arrayView1d< TableFunction::KernelWrapper const > const & capPresKernelWrappers, + arrayView1d< TableFunction::KernelWrapper const > const & inverseCapPresWrappers, arrayView1d< integer const > const & phaseTypes, arrayView1d< integer const > const & phaseOrder, arrayView3d< real64, cappres::USD_CAPPRES > const & phaseCapPres, @@ -67,8 +68,8 @@ class TableCapillaryPressure : public CapillaryPressureBase GEOS_HOST_DEVICE void computeInv( arraySlice1d< real64, compflow::USD_PHASE - 1 > const & phaseVolFraction, - arraySlice1d< real64 const, cappres::USD_CAPPRES - 2 > const & phaseCapPres, - arraySlice2d< real64, cappres::USD_CAPPRES_DS - 2 > const & dPhaseCapPres_dPhaseVolFrac ) const; + arraySlice1d< real64 const, cappres::USD_CAPPRES - 2 > const & phaseCapPres, + arraySlice2d< real64, cappres::USD_CAPPRES_DS - 2 > const & dPhaseCapPres_dPhaseVolFrac ) const; GEOS_HOST_DEVICE @@ -81,6 +82,7 @@ class TableCapillaryPressure : public CapillaryPressureBase /// Array of kernel wrappers for the capillary pressures /// Is of size 1 for two-phase flow, and of size 2 for three-phase flow arrayView1d< TableFunction::KernelWrapper const > const m_capPresKernelWrappers; + arrayView1d< TableFunction::KernelWrapper const > const m_inverseCapPresWrappers; }; @@ -97,6 +99,7 @@ class TableCapillaryPressure : public CapillaryPressureBase static constexpr char const * wettingIntermediateCapPresTableNameString() { return "wettingIntermediateCapPressureTableName"; } static constexpr char const * nonWettingIntermediateCapPresTableNameString() { return "nonWettingIntermediateCapPressureTableName"; } static constexpr char const * capPresWrappersString() { return "capPresWrappers"; } + static constexpr char const * inverseCapPresWrappersString() { return "inverseCapPresWrappers"; } }; @@ -122,6 +125,9 @@ class TableCapillaryPressure : public CapillaryPressureBase /// Capillary pressure kernel wrapper for the first pair (wetting-intermediate if NP=3, wetting-non-wetting otherwise) array1d< TableFunction::KernelWrapper > m_capPresKernelWrappers; + array1d< TableFunction::KernelWrapper > m_inverseCapPresWrappers; + + std::vector< std::shared_ptr > m_inverseTables; }; @@ -183,24 +189,33 @@ GEOS_HOST_DEVICE inline void TableCapillaryPressure::KernelWrapper:: computeInv( arraySlice1d< real64, compflow::USD_PHASE - 1 > const & phaseVolFraction, - arraySlice1d< real64 const, cappres::USD_CAPPRES - 2 > const & phaseCapPres, - arraySlice2d< real64, cappres::USD_CAPPRES_DS - 2 > const & dPhaseCapPres_dPhaseVolFrac ) const + arraySlice1d< real64 const, cappres::USD_CAPPRES - 2 > const & phaseCapPres, + arraySlice2d< real64, cappres::USD_CAPPRES_DS - 2 > const & dPhaseCapPres_dPhaseVolFrac ) const { LvArray::forValuesInSlice( dPhaseCapPres_dPhaseVolFrac, []( real64 & val ){ val = 0.0; } ); using PT = CapillaryPressureBase::PhaseType; integer const ipWater = m_phaseOrder[PT::WATER]; - // integer const ipOil = m_phaseOrder[PT::OIL]; - // integer const ipGas = m_phaseOrder[PT::GAS]; + integer const ipOil = m_phaseOrder[PT::OIL]; + integer const ipGas = m_phaseOrder[PT::GAS]; - // put capillary pressure on the wetting phase + // put capillary pressure on the wetting phase + real64 capPresWater = phaseCapPres[ipWater]; + array1d input(1); + input[0] = capPresWater; + auto inputSlice = input.toSliceConst(); - phaseVolFraction[ipWater] = - m_capPresKernelWrappers[0].compute( &(phaseCapPres)[ipWater], - &(dPhaseCapPres_dPhaseVolFrac)[ipWater][ipWater] ); + phaseVolFraction[ipWater] = + m_capPresKernelWrappers[0].compute( &(phaseCapPres)[ipWater], + &(dPhaseCapPres_dPhaseVolFrac)[ipWater][ipWater] ); + phaseVolFraction[ipWater] = + m_inverseCapPresWrappers[0].compute( inputSlice, + &(dPhaseCapPres_dPhaseVolFrac)[ipWater][ipWater] ); + phaseVolFraction[ipGas] = 1.0 - phaseVolFraction[ipWater]; } + GEOS_HOST_DEVICE inline void TableCapillaryPressure::KernelWrapper:: diff --git a/src/coreComponents/constitutive/capillaryPressure/VanGenuchtenCapillaryPressure.hpp b/src/coreComponents/constitutive/capillaryPressure/VanGenuchtenCapillaryPressure.hpp index 14944dd980b..d068bfd6543 100644 --- a/src/coreComponents/constitutive/capillaryPressure/VanGenuchtenCapillaryPressure.hpp +++ b/src/coreComponents/constitutive/capillaryPressure/VanGenuchtenCapillaryPressure.hpp @@ -56,6 +56,11 @@ class VanGenuchtenCapillaryPressureUpdate final : public CapillaryPressureBaseUp void compute( arraySlice1d< real64 const, compflow::USD_PHASE - 1 > const & phaseVolFraction, arraySlice1d< real64, cappres::USD_CAPPRES - 2 > const & phaseCapPres, arraySlice2d< real64, cappres::USD_CAPPRES_DS - 2 > const & dPhaseCapPres_dPhaseVolFrac ) const; + + GEOS_HOST_DEVICE + void computeInv( arraySlice1d< real64 const, compflow::USD_PHASE - 1 > const & phaseVolFraction, + arraySlice1d< real64, cappres::USD_CAPPRES - 2 > const & phaseCapPres, + arraySlice2d< real64, cappres::USD_CAPPRES_DS - 2 > const & dPhaseCapPres_dPhaseVolFrac ) const; GEOS_HOST_DEVICE virtual void update( localIndex const k, @@ -191,6 +196,69 @@ VanGenuchtenCapillaryPressureUpdate:: } } +GEOS_HOST_DEVICE +inline void +VanGenuchtenCapillaryPressureUpdate:: + computeInv( arraySlice1d< real64 const, compflow::USD_PHASE - 1 > const & phaseVolFraction, + arraySlice1d< real64, cappres::USD_CAPPRES - 2 > const & phaseCapPres, + arraySlice2d< real64, cappres::USD_CAPPRES_DS - 2 > const & dPhaseCapPres_dPhaseVolFrac ) const +{ + LvArray::forValuesInSlice( dPhaseCapPres_dPhaseVolFrac, []( real64 & val ){ val = 0.0; } ); + + // the VanGenuchten model does not support volFracScaled = 0 and = 1 + // hence we need an epsilon value to avoid a division by zero + // TODO: for S < epsilon and S > 1 - epsilon, replace the original unbounded VG curve with a bounded power-law + // extension + real64 const eps = m_capPressureEpsilon; + real64 const volFracScaleInv = 1.0 / m_volFracScale; + + // compute first water-oil capillary pressure as a function of water-phase vol fraction + integer const ip_water = m_phaseOrder[CapillaryPressureBase::PhaseType::WATER]; + if( ip_water >= 0 ) + { + + real64 const volFracScaled = (phaseVolFraction[ip_water] - m_phaseMinVolumeFraction[ip_water]) * volFracScaleInv; + real64 const exponentInv = m_phaseCapPressureExponentInv[ip_water]; // div by 0 taken care of by initialization + // check + real64 const multiplier = m_phaseCapPressureMultiplier[ip_water]; + + real64 const scaledWettingVolFrac = volFracScaled; + real64 const dScaledWettingPhaseVolFrac_dVolFrac = volFracScaleInv; + + evaluateVanGenuchtenFunction( scaledWettingVolFrac, + dScaledWettingPhaseVolFrac_dVolFrac, + exponentInv, + multiplier, + eps, + phaseCapPres[ip_water], + dPhaseCapPres_dPhaseVolFrac[ip_water][ip_water] ); + + } + + + // then compute the oil-gas capillary pressure as a function of gas-phase vol fraction + integer const ip_gas = m_phaseOrder[CapillaryPressureBase::PhaseType::GAS]; + if( ip_gas >= 0 ) + { + real64 const volFracScaled = (phaseVolFraction[ip_gas] - m_phaseMinVolumeFraction[ip_gas]) * volFracScaleInv; + real64 const exponentInv = m_phaseCapPressureExponentInv[ip_gas]; // div by 0 taken care of by initialization + // check + real64 const multiplier = -m_phaseCapPressureMultiplier[ip_gas]; // for gas capillary pressure, take the opposite + // of the VG function + + real64 const scaledWettingVolFrac = 1-volFracScaled; + real64 const dScaledWettingPhaseVolFrac_dVolFrac = -volFracScaleInv; + + evaluateVanGenuchtenFunction( scaledWettingVolFrac, + dScaledWettingPhaseVolFrac_dVolFrac, + exponentInv, + multiplier, + eps, + phaseCapPres[ip_gas], + dPhaseCapPres_dPhaseVolFrac[ip_gas][ip_gas] ); + } +} + GEOS_HOST_DEVICE GEOS_FORCE_INLINE void diff --git a/src/coreComponents/constitutive/unitTests/FluidModelTest_impl.hpp b/src/coreComponents/constitutive/unitTests/FluidModelTest_impl.hpp index 72cfec6501c..ce731e6b775 100644 --- a/src/coreComponents/constitutive/unitTests/FluidModelTest_impl.hpp +++ b/src/coreComponents/constitutive/unitTests/FluidModelTest_impl.hpp @@ -35,7 +35,7 @@ template< typename FLUID_TYPE, integer NUM_COMP, integer NUM_PHASE > FluidModelTest< FLUID_TYPE, NUM_COMP, NUM_PHASE >::FluidModelTest(): m_parent( "parent", m_node ) { - createFunctionManager(); + // createFunctionManager(); } template< typename FLUID_TYPE, integer NUM_COMP, integer NUM_PHASE > diff --git a/src/coreComponents/finiteVolume/CellElementStencilTPFA.hpp b/src/coreComponents/finiteVolume/CellElementStencilTPFA.hpp index 391d614baba..5c468d293cf 100644 --- a/src/coreComponents/finiteVolume/CellElementStencilTPFA.hpp +++ b/src/coreComponents/finiteVolume/CellElementStencilTPFA.hpp @@ -71,19 +71,19 @@ class CellElementStencilTPFAWrapper : public StencilWrapperBase< TwoPointStencil real64 ( &weight )[1][2], real64 ( &dWeight_dVar )[1][2] ) const; /** - * @brief Compute half weights and derivatives w.r.t to one variable. - * @param[in] iconn connection index - * @param[in] coefficient view accessor to the coefficient used to compute the weights - * @param[in] dCoeff_dVar view accessor to the derivative of the coefficient w.r.t to the variable - * @param[out] weight view weights - * @param[out] dWeight_dVar derivative of the weights w.r.t to the variable - */ + * @brief Compute half weights and derivatives w.r.t to one variable. + * @param[in] iconn connection index + * @param[in] coefficient view accessor to the coefficient used to compute the weights + * @param[in] dCoeff_dVar view accessor to the derivative of the coefficient w.r.t to the variable + * @param[out] weight view weights + * @param[out] dWeight_dVar derivative of the weights w.r.t to the variable + */ GEOS_HOST_DEVICE void computeHalfWeights( localIndex const iconn, - CoefficientAccessor< arrayView3d< real64 const > > const & coefficient, - CoefficientAccessor< arrayView3d< real64 const > > const & dCoeff_dVar, - real64 ( &weight )[1][2], - real64 ( &dWeight_dVar )[1][2] ) const; + CoefficientAccessor< arrayView3d< real64 const > > const & coefficient, + CoefficientAccessor< arrayView3d< real64 const > > const & dCoeff_dVar, + real64 ( &weight )[1][2], + real64 ( &dWeight_dVar )[1][2] ) const; /** * @brief Compute weights and derivatives w.r.t to one variable without coefficient @@ -311,10 +311,10 @@ GEOS_HOST_DEVICE inline void CellElementStencilTPFAWrapper:: computeHalfWeights( localIndex const iconn, - CoefficientAccessor< arrayView3d< real64 const > > const & coefficient, - CoefficientAccessor< arrayView3d< real64 const > > const & dCoeff_dVar, - real64 (& weight)[1][2], - real64 (& dWeight_dVar )[1][2] ) const + CoefficientAccessor< arrayView3d< real64 const > > const & coefficient, + CoefficientAccessor< arrayView3d< real64 const > > const & dCoeff_dVar, + real64 (& weight)[1][2], + real64 (& dWeight_dVar )[1][2] ) const { real64 halfWeight[2]; real64 dHalfWeight_dVar[2]; @@ -371,8 +371,10 @@ CellElementStencilTPFAWrapper:: // real64 dHarmonicWeight_dVar[2]; // real64 dArithmeticWeight_dVar[2]; - // dHarmonicWeight_dVar[0] = sum > 0 ? (dHalfWeight_dVar[0]*sum*halfWeight[1] - dHalfWeight_dVar[0]*halfWeight[0]*halfWeight[1]) / ( sum*sum ) : 0.0; - // dHarmonicWeight_dVar[1] = sum > 0 ? (dHalfWeight_dVar[1]*sum*halfWeight[0] - dHalfWeight_dVar[1]*halfWeight[1]*halfWeight[0]) / ( sum*sum ) : 0.0; + // dHarmonicWeight_dVar[0] = sum > 0 ? (dHalfWeight_dVar[0]*sum*halfWeight[1] - dHalfWeight_dVar[0]*halfWeight[0]*halfWeight[1]) / ( + // sum*sum ) : 0.0; + // dHarmonicWeight_dVar[1] = sum > 0 ? (dHalfWeight_dVar[1]*sum*halfWeight[0] - dHalfWeight_dVar[1]*halfWeight[1]*halfWeight[0]) / ( + // sum*sum ) : 0.0; // dArithmeticWeight_dVar[0] = dHalfWeight_dVar[0] / 2; // dArithmeticWeight_dVar[1] = dHalfWeight_dVar[1] / 2; diff --git a/src/coreComponents/finiteVolume/EmbeddedSurfaceToCellStencil.hpp b/src/coreComponents/finiteVolume/EmbeddedSurfaceToCellStencil.hpp index 27462c5b516..4a191ca7614 100644 --- a/src/coreComponents/finiteVolume/EmbeddedSurfaceToCellStencil.hpp +++ b/src/coreComponents/finiteVolume/EmbeddedSurfaceToCellStencil.hpp @@ -109,10 +109,10 @@ class EmbeddedSurfaceToCellStencilWrapper : public StencilWrapperBase< TwoPointS GEOS_HOST_DEVICE void computeHalfWeights( localIndex const iconn, - CoefficientAccessor< arrayView3d< real64 const > > const & coefficient, - CoefficientAccessor< arrayView3d< real64 const > > const & dCoeff_dVar, - real64 ( &weight )[1][2], - real64 ( &dWeight_dVar )[1][2] ) const; + CoefficientAccessor< arrayView3d< real64 const > > const & coefficient, + CoefficientAccessor< arrayView3d< real64 const > > const & dCoeff_dVar, + real64 ( &weight )[1][2], + real64 ( &dWeight_dVar )[1][2] ) const; /** * @brief Compute weigths and derivatives w.r.t to one variable without coefficient @@ -263,10 +263,10 @@ GEOS_HOST_DEVICE inline void EmbeddedSurfaceToCellStencilWrapper:: computeHalfWeights( localIndex iconn, - CoefficientAccessor< arrayView3d< real64 const > > const & coefficient, - CoefficientAccessor< arrayView3d< real64 const > > const & dCoeff_dVar, - real64 ( & weight )[1][2], - real64 ( & dWeight_dVar )[1][2] ) const + CoefficientAccessor< arrayView3d< real64 const > > const & coefficient, + CoefficientAccessor< arrayView3d< real64 const > > const & dCoeff_dVar, + real64 ( & weight )[1][2], + real64 ( & dWeight_dVar )[1][2] ) const { localIndex const er0 = m_elementRegionIndices[iconn][0]; localIndex const esr0 = m_elementSubRegionIndices[iconn][0]; diff --git a/src/coreComponents/finiteVolume/FaceElementToCellStencil.hpp b/src/coreComponents/finiteVolume/FaceElementToCellStencil.hpp index a01a4541e85..2376fd89ccf 100644 --- a/src/coreComponents/finiteVolume/FaceElementToCellStencil.hpp +++ b/src/coreComponents/finiteVolume/FaceElementToCellStencil.hpp @@ -107,19 +107,19 @@ class FaceElementToCellStencilWrapper : public StencilWrapperBase< TwoPointStenc real64 ( &dWeight_dVar )[1][2] ) const; /** - * @brief Compute half weigths and derivatives w.r.t to one variable. - * @param[in] iconn connection index - * @param[in] coefficient view accessor to the coefficient used to compute the weights - * @param[in] dCoeff_dVar view accessor to the derivative of the coefficient w.r.t to the variable - * @param[out] weight view weights - * @param[out] dWeight_dVar derivative of the weigths w.r.t to the variable - */ + * @brief Compute half weigths and derivatives w.r.t to one variable. + * @param[in] iconn connection index + * @param[in] coefficient view accessor to the coefficient used to compute the weights + * @param[in] dCoeff_dVar view accessor to the derivative of the coefficient w.r.t to the variable + * @param[out] weight view weights + * @param[out] dWeight_dVar derivative of the weigths w.r.t to the variable + */ GEOS_HOST_DEVICE void computeHalfWeights( localIndex iconn, - CoefficientAccessor< arrayView3d< real64 const > > const & coefficient, - CoefficientAccessor< arrayView3d< real64 const > > const & dCoeff_dVar, - real64 ( &weight )[1][2], - real64 ( &dWeight_dVar )[1][2] ) const; + CoefficientAccessor< arrayView3d< real64 const > > const & coefficient, + CoefficientAccessor< arrayView3d< real64 const > > const & dCoeff_dVar, + real64 ( &weight )[1][2], + real64 ( &dWeight_dVar )[1][2] ) const; /** * @brief Compute weigths and derivatives w.r.t to one variable without coefficient @@ -307,10 +307,10 @@ inline void FaceElementToCellStencilWrapper:: GEOS_HOST_DEVICE inline void FaceElementToCellStencilWrapper:: computeHalfWeights( localIndex const iconn, - CoefficientAccessor< arrayView3d< real64 const > > const & coefficient, - CoefficientAccessor< arrayView3d< real64 const > > const & dCoeff_dVar, - real64 ( & weight )[1][2], - real64 ( & dWeight_dVar )[1][2] ) const + CoefficientAccessor< arrayView3d< real64 const > > const & coefficient, + CoefficientAccessor< arrayView3d< real64 const > > const & dCoeff_dVar, + real64 ( & weight )[1][2], + real64 ( & dWeight_dVar )[1][2] ) const { localIndex const er0 = m_elementRegionIndices[iconn][0]; localIndex const esr0 = m_elementSubRegionIndices[iconn][0]; diff --git a/src/coreComponents/finiteVolume/SurfaceElementStencil.hpp b/src/coreComponents/finiteVolume/SurfaceElementStencil.hpp index 2f0feb536fd..4c982dbef4a 100644 --- a/src/coreComponents/finiteVolume/SurfaceElementStencil.hpp +++ b/src/coreComponents/finiteVolume/SurfaceElementStencil.hpp @@ -120,10 +120,10 @@ class SurfaceElementStencilWrapper : public StencilWrapperBase< SurfaceElementSt */ GEOS_HOST_DEVICE void computeHalfWeights( localIndex iconn, - CoefficientAccessor< arrayView3d< real64 const > > const & coefficient, - CoefficientAccessor< arrayView3d< real64 const > > const & dCoeff_dVar, - real64 ( &weight )[maxNumConnections][2], - real64 ( &dWeight_dVar )[maxNumConnections][2] ) const; + CoefficientAccessor< arrayView3d< real64 const > > const & coefficient, + CoefficientAccessor< arrayView3d< real64 const > > const & dCoeff_dVar, + real64 ( &weight )[maxNumConnections][2], + real64 ( &dWeight_dVar )[maxNumConnections][2] ) const; /** * @brief Compute weights and derivatives w.r.t to one variable without coefficient @@ -383,10 +383,10 @@ GEOS_HOST_DEVICE inline void SurfaceElementStencilWrapper:: computeHalfWeights( localIndex iconn, - CoefficientAccessor< arrayView3d< real64 const > > const & coefficient, - CoefficientAccessor< arrayView3d< real64 const > > const & dCoeff_dVar, - real64 ( & weight )[maxNumConnections][2], - real64 ( & dWeight_dVar )[maxNumConnections][2] ) const + CoefficientAccessor< arrayView3d< real64 const > > const & coefficient, + CoefficientAccessor< arrayView3d< real64 const > > const & dCoeff_dVar, + real64 ( & weight )[maxNumConnections][2], + real64 ( & dWeight_dVar )[maxNumConnections][2] ) const { real64 sumOfTrans = 0.0; diff --git a/src/coreComponents/integrationTests/fluidFlowTests/testImmiscibleInterfaceConditions.cpp b/src/coreComponents/integrationTests/fluidFlowTests/testImmiscibleInterfaceConditions.cpp new file mode 100644 index 00000000000..95431c366a4 --- /dev/null +++ b/src/coreComponents/integrationTests/fluidFlowTests/testImmiscibleInterfaceConditions.cpp @@ -0,0 +1,677 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * SPDX-License-Identifier: LGPL-2.1-only + * + * Copyright (c) 2016-2024 Lawrence Livermore National Security LLC + * Copyright (c) 2018-2024 TotalEnergies + * Copyright (c) 2018-2024 The Board of Trustees of the Leland Stanford Junior University + * Copyright (c) 2023-2024 Chevron + * Copyright (c) 2019- GEOS/GEOSX Contributors + * All rights reserved + * + * See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details. + * ------------------------------------------------------------------------------------------------------------ + */ +#define phase0MinSat1 0.0 +#define phase1MinSat1 0.0 +#define phase0MinSat2 0.0 +#define phase1MinSat2 0.0 + + +#include +#include + +#include "mainInterface/initialization.hpp" +#include "mainInterface/GeosxState.hpp" +#include "constitutive/fluid/twophaseimmisciblefluid/TwoPhaseImmiscibleFluid.hpp" +#include "physicsSolvers/PhysicsSolverManager.hpp" +#include "physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp" +#include "unitTests/fluidFlowTests/testCompFlowUtils.hpp" +#include "constitutive/unitTests/FluidModelTest.hpp" +#include "constitutive/unitTests/FluidModelTest_impl.hpp" +#include "common/initializeEnvironment.hpp" +#include "unitTests/constitutiveTests/constitutiveTestHelpers.hpp" +#include "functions/FunctionManager.hpp" +#include "constitutive/capillaryPressure/CapillaryPressureFields.hpp" + +#include + + + +using namespace geos; +using namespace geos::dataRepository; +using namespace geos::constitutive; +using namespace geos::testing; + +CommandLineOptions g_commandLineOptions; + +TwoPhaseImmiscibleFluid * makeTwoPhaseImmiscibleFluid( TwoPhaseImmiscibleFluid & fluid ) +{ + + FunctionManager & functionManager = FunctionManager::getInstance(); + + // 1D table with linear interpolation + localIndex constexpr Naxis = 6; + localIndex constexpr NaxisSingle = 1; + + real64_array densityCoordPhase0; + // fill( densityCoordPhase0, Feed< Naxis >{ 0.22, 0.3, 0.5, 0.6, 0.8, 1.0 } ); + for (auto v : {0.0}) + densityCoordPhase0.emplace_back(v); + real64_array densityValuesPhase0; + // fill( densityValuesPhase0, Feed< Naxis >{ 0.00603, 0.04224, 0.04224, 0.22423, 0.31311, 0.40203 } ); + for (auto v : {1000.0}) + densityValuesPhase0.emplace_back(v); + + real64_array densityCoordPhase1; + // fill( densityCoordPhase1, Feed< Naxis >{ 1.22, 1.3, 1.5, 1.6, 1.8, 2.0 } ); + for (auto v : {0.0}) + densityCoordPhase1.emplace_back(v); + real64_array densityValuesPhase1; + // fill( densityValuesPhase1, Feed< Naxis >{ 0.00603, 0.04224, 0.04224, 0.22423, 0.31311, 0.40203 } ); + for (auto v : {100.0}) + densityValuesPhase1.emplace_back(v); + + real64_array viscosityCoordPhase0; + // fill( viscosityCoordPhase0, Feed< Naxis >{ 0.22, 0.3, 0.5, 0.6, 0.8, 1.0 } ); + for (auto v : {0.0}) + viscosityCoordPhase0.emplace_back(v); + real64_array viscosityValuesPhase0; + // fill( viscosityValuesPhase0, Feed< Naxis >{ 40203, 31311, 22423, 15011, 4224, 603 } ); + for (auto v : {0.001}) + viscosityValuesPhase0.emplace_back(v); + + real64_array viscosityCoordPhase1; + // fill( viscosityCoordPhase1, Feed< NaxisSingle >{ 0.22 } ); + for (auto v : {0.0}) + viscosityCoordPhase1.emplace_back(v); + + real64_array viscosityValuesPhase1; + // fill( viscosityValuesPhase1, Feed< NaxisSingle >{ 45 } ); + for (auto v : {0.001}) + viscosityValuesPhase1.emplace_back(v); + + TableFunction & table_density0 = dynamicCast< TableFunction & >( *functionManager.createChild( "TableFunction", "densityTablePhase0" ) ); + array1d coords_density0; + coords_density0.emplace_back(densityCoordPhase0); + table_density0.setTableCoordinates( coords_density0, { units::Dimensionless } ); + table_density0.setTableValues( densityValuesPhase0, units::Dimensionless ); + table_density0.reInitializeFunction(); + + table_density0.setInterpolationMethod( TableFunction::InterpolationType::Linear ); + + TableFunction & table_density1 = dynamicCast< TableFunction & >( *functionManager.createChild( "TableFunction", "densityTablePhase1" ) ); + array1d coords_density1; + coords_density1.emplace_back(densityCoordPhase1); + table_density1.setTableCoordinates( coords_density1, { units::Dimensionless } ); + table_density1.setTableValues( densityValuesPhase1, units::Dimensionless ); + table_density1.reInitializeFunction(); + + table_density1.setInterpolationMethod( TableFunction::InterpolationType::Linear ); + + TableFunction & table_viscosity0 = dynamicCast< TableFunction & >( *functionManager.createChild( "TableFunction", "viscosityTablePhase0" ) ); + array1d coords_viscosity0; + coords_viscosity0.emplace_back(viscosityCoordPhase0); + table_viscosity0.setTableCoordinates( coords_viscosity0, { units::Dimensionless } ); + table_viscosity0.setTableValues( viscosityValuesPhase0, units::Dimensionless ); + table_viscosity0.reInitializeFunction(); + + table_viscosity0.setInterpolationMethod( TableFunction::InterpolationType::Linear ); + + TableFunction & table_viscosity1 = dynamicCast< TableFunction & >( *functionManager.createChild( "TableFunction", "viscosityTablePhase1" ) ); + array1d coords_viscosity1; + coords_viscosity1.emplace_back(viscosityCoordPhase1); + table_viscosity1.setTableCoordinates( coords_viscosity1, { units::Dimensionless } ); + table_viscosity1.setTableValues( viscosityValuesPhase1, units::Dimensionless ); + table_viscosity1.reInitializeFunction(); + + table_viscosity1.setInterpolationMethod( TableFunction::InterpolationType::Linear ); + + + // createTable( "densityTablePhase0", densityCoordPhase0, densityValuesPhase0 ); + // createTable( "densityTablePhase1", densityCoordPhase1, densityValuesPhase1 ); + // createTable( "viscosityTablePhase0", viscosityCoordPhase0, viscosityValuesPhase0 ); + // createTable( "viscosityTablePhase1", viscosityCoordPhase1, viscosityValuesPhase1 ); + + // 2) Set up the constitutive model + + string_array & phaseNames = fluid.getReference< string_array >( TwoPhaseImmiscibleFluid::viewKeyStruct::phaseNamesString() ); + phaseNames.emplace_back( "water" ); + phaseNames.emplace_back( "gas" ); + + string_array & densityTableNames = fluid.getReference< string_array >( TwoPhaseImmiscibleFluid::viewKeyStruct::densityTableNamesString() ); + densityTableNames.emplace_back( "densityTablePhase0" ); + densityTableNames.emplace_back( "densityTablePhase1" ); + + string_array & viscosityTableNames = fluid.getReference< string_array >( TwoPhaseImmiscibleFluid::viewKeyStruct::viscosityTableNamesString() ); + viscosityTableNames.emplace_back( "viscosityTablePhase0" ); + viscosityTableNames.emplace_back( "viscosityTablePhase1" ); + + fluid.postInputInitializationRecursive(); + fluid.initialize(); // to test all the checks + + return &fluid; +} + +CapillaryPressureBase & makeJFunctionCapPressureTwoPhase( string const & name, Group & parent ) +{ + FunctionManager & functionManager = FunctionManager::getInstance(); + + // 1) First, define the tables + + // // 1D table, various interpolation methods + // localIndex const Naxis = 12; + + // // Setup table + // array1d< real64_array > coordinates; + // coordinates.resize( 1 ); + // coordinates[0].resize( Naxis ); + + // coordinates[0][0] = 0.0; + // coordinates[0][1] = 0.05; + // coordinates[0][2] = 0.15; + // coordinates[0][3] = 0.25; + // coordinates[0][4] = 0.35; + // coordinates[0][5] = 0.45; + // coordinates[0][6] = 0.55; + // coordinates[0][7] = 0.65; + // coordinates[0][8] = 0.75; + // coordinates[0][9] = 0.85; + // coordinates[0][10] = 0.95; + // coordinates[0][11] = 1.0; + + // real64_array values( Naxis ); + // values[0] = 4.331729359; + // values[1] = 3.523266264; + // values[2] = 2.677103439; + // values[3] = 2.356150157; + // values[4] = 2.166062360; + // values[5] = 2.034158727; + // values[6] = 1.934627222; + // values[7] = 1.855494313; + // values[8] = 1.790286970; + // values[9] = 1.735134860; + // values[10] = 1.687551617; + // values[11] = 1.666049754; + + + localIndex const Naxis = 2; + + // Setup table + array1d< real64_array > coordinates; + coordinates.resize( 1 ); + coordinates[0].resize( Naxis ); + + coordinates[0][0] = 0.0; + coordinates[0][1] = 1.0; + + real64_array values( Naxis ); + values[0] = 4.331729359; + values[1] = 1.666049754; + + + TableFunction & table_w = dynamicCast< TableFunction & >( *functionManager.createChild( "TableFunction", "water_jFunction" ) ); + table_w.setTableCoordinates( coordinates, { units::Dimensionless } ); + table_w.setTableValues( values, units::Dimensionless ); + table_w.reInitializeFunction(); + + table_w.setInterpolationMethod( TableFunction::InterpolationType::Linear ); + + // 2) Then set up the constitutive model + + JFunctionCapillaryPressure & capPressure = parent.registerGroup< JFunctionCapillaryPressure >( name ); + + string_array & phaseNames = capPressure.getReference< string_array >( CapillaryPressureBase::viewKeyStruct::phaseNamesString() ); + phaseNames.resize( 2 ); + phaseNames[0] = "water"; phaseNames[1] = "gas"; + + auto & waterTableName = capPressure.getReference< string >( JFunctionCapillaryPressure::viewKeyStruct::wettingNonWettingJFuncTableNameString() ); + waterTableName = "water_jFunction"; + + auto & surfaceTension = capPressure.getReference< real64 >( JFunctionCapillaryPressure::viewKeyStruct::wettingNonWettingSurfaceTensionString() ); + //surfaceTension = 23.86955676433857e-3; + surfaceTension = 0.02; + + auto & permeabilityDirection = + capPressure.getReference< JFunctionCapillaryPressure::PermeabilityDirection >( JFunctionCapillaryPressure::viewKeyStruct::permeabilityDirectionString() ); + permeabilityDirection = JFunctionCapillaryPressure::PermeabilityDirection::XY; + + capPressure.postInputInitializationRecursive(); + capPressure.initialize(); // to test all the checks + + return capPressure; +} + +CapillaryPressureBase & makeTableCapPressureTwoPhase1( string const & name, Group & parent ) +{ + FunctionManager & functionManager = FunctionManager::getInstance(); + + // 1) First, define the tables + + // 1D table, various interpolation methods + localIndex Naxis = 12; + + // Setup table + array1d< real64_array > coordinates; + coordinates.resize( 1 ); + coordinates[0].resize( Naxis ); + coordinates[0][0] = 0.0; + coordinates[0][1] = 0.05; + coordinates[0][2] = 0.15; + coordinates[0][3] = 0.25; + coordinates[0][4] = 0.35; + coordinates[0][5] = 0.45; + coordinates[0][6] = 0.55; + coordinates[0][7] = 0.65; + coordinates[0][8] = 0.75; + coordinates[0][9] = 0.85; + coordinates[0][10] = 0.95; + coordinates[0][11] = 1.0; + + real64_array values( Naxis ); + values[0] = 130000.0; + values[1] = 90572.79; + values[2] = 49307.11; + values[3] = 33654.85; + values[4] = 24384.64; + values[5] = 17951.96; + values[6] = 13098; + values[7] = 9238.84; + values[8] = 6058.81; + values[9] = 3369.14; + values[10] = 1048.6; + values[11] = 0.0; + + // localIndex const Naxis = 2; + + // // Setup table + // array1d< real64_array > coordinates; + // coordinates.resize( 1 ); + // coordinates[0].resize( Naxis ); + + // coordinates[0][0] = 0.0; + // coordinates[0][1] = 1.0; + + // real64_array values( Naxis ); + // values[0] = 129999.999994362; + // values[1] = 50000.0000139914; + + + TableFunction & table_w = dynamicCast< TableFunction & >( *functionManager.createChild( "TableFunction", "water_pc" ) ); + table_w.setTableCoordinates( coordinates, { units::Dimensionless } ); + table_w.setTableValues( values, units::Pressure ); + table_w.reInitializeFunction(); + + table_w.setInterpolationMethod( TableFunction::InterpolationType::Linear ); + + // 2) Then set up the constitutive model + + TableCapillaryPressure & capPressure = parent.registerGroup< TableCapillaryPressure >( name ); + + string_array & phaseNames = capPressure.getReference< string_array >( CapillaryPressureBase::viewKeyStruct::phaseNamesString() ); + phaseNames.resize( 2 ); + phaseNames[0] = "water"; phaseNames[1] = "gas"; + + auto & waterTableName = capPressure.getReference< string >( TableCapillaryPressure::viewKeyStruct::wettingNonWettingCapPresTableNameString() ); + waterTableName = "water_pc"; + + capPressure.postInputInitializationRecursive(); + capPressure.initialize(); // to test all the checks + return capPressure; +} + +CapillaryPressureBase & makeTableCapPressureTwoPhase2( string const & name, Group & parent ) +{ + FunctionManager & functionManager = FunctionManager::getInstance(); + + // 1) First, define the tables + + // 1D table, various interpolation methods + localIndex Naxis = 12; + + // Setup table + array1d< real64_array > coordinates; + coordinates.resize( 1 ); + coordinates[0].resize( Naxis ); + coordinates[0][0] = 0.0; + coordinates[0][1] = 0.05; + coordinates[0][2] = 0.15; + coordinates[0][3] = 0.25; + coordinates[0][4] = 0.35; + coordinates[0][5] = 0.45; + coordinates[0][6] = 0.55; + coordinates[0][7] = 0.65; + coordinates[0][8] = 0.75; + coordinates[0][9] = 0.85; + coordinates[0][10] = 0.95; + coordinates[0][11] = 1.0; + + real64_array values( Naxis ); + values[0] = 195000.0; + values[1] = 135859.25; + values[2] = 73960.67; + values[3] = 50482.28; + values[4] = 36576.96; + values[5] = 26927.94; + values[6] = 19647; + values[7] = 13858.26; + values[8] = 9088.2; + values[9] = 5053.72; + values[10] = 1572.9; + values[11] = 0.0; + + // localIndex const Naxis = 2; + + // // Setup table + // array1d< real64_array > coordinates; + // coordinates.resize( 1 ); + // coordinates[0].resize( Naxis ); + + // coordinates[0][0] = 0.0; + // coordinates[0][1] = 1.0; + + // real64_array values( Naxis ); + // values[0] = 129999.999994362; + // values[1] = 50000.0000139914; + + + TableFunction & table_w = dynamicCast< TableFunction & >( *functionManager.createChild( "TableFunction", "water_pc" ) ); + table_w.setTableCoordinates( coordinates, { units::Dimensionless } ); + table_w.setTableValues( values, units::Pressure ); + table_w.reInitializeFunction(); + + table_w.setInterpolationMethod( TableFunction::InterpolationType::Linear ); + + // 2) Then set up the constitutive model + + TableCapillaryPressure & capPressure = parent.registerGroup< TableCapillaryPressure >( name ); + + string_array & phaseNames = capPressure.getReference< string_array >( CapillaryPressureBase::viewKeyStruct::phaseNamesString() ); + phaseNames.resize( 2 ); + phaseNames[0] = "water"; phaseNames[1] = "gas"; + + auto & waterTableName = capPressure.getReference< string >( TableCapillaryPressure::viewKeyStruct::wettingNonWettingCapPresTableNameString() ); + waterTableName = "water_pc"; + + capPressure.postInputInitializationRecursive(); + capPressure.initialize(); // to test all the checks + return capPressure; +} + +CapillaryPressureBase & makeBrooksCoreyCapPressureTwoPhase1( string const & name, Group & parent ) +{ + BrooksCoreyCapillaryPressure & capPressure = parent.registerGroup< BrooksCoreyCapillaryPressure >( name ); + + string_array & phaseNames = capPressure.getReference< string_array >( CapillaryPressureBase::viewKeyStruct::phaseNamesString() ); + phaseNames.resize( 2 ); + phaseNames[0] = "water"; phaseNames[1] = "gas"; + + array1d< real64 > & phaseMinSat = capPressure.getReference< array1d< real64 > >( BrooksCoreyCapillaryPressure::viewKeyStruct::phaseMinVolumeFractionString() ); + phaseMinSat.resize( 2 ); + phaseMinSat[0] = phase0MinSat1; phaseMinSat[1] = phase1MinSat1; + + array1d< real64 > & phaseCapPressureExpInv = + capPressure.getReference< array1d< real64 > >( BrooksCoreyCapillaryPressure::viewKeyStruct::phaseCapPressureExponentInvString() ); + phaseCapPressureExpInv.resize( 2 ); + phaseCapPressureExpInv[0] = 4; phaseCapPressureExpInv[1] = 1; + + array1d< real64 > & phaseEntryPressure = capPressure.getReference< array1d< real64 > >( BrooksCoreyCapillaryPressure::viewKeyStruct::phaseEntryPressureString() ); + phaseEntryPressure.resize( 2 ); + phaseEntryPressure[0] = 0.75e5; phaseEntryPressure[1] = 0; + + real64 & capPressureEpsilon = capPressure.getReference< real64 >( BrooksCoreyCapillaryPressure::viewKeyStruct::capPressureEpsilonString() ); + capPressureEpsilon = 1.0e-8; + + capPressure.postInputInitializationRecursive(); + return capPressure; +} + +CapillaryPressureBase & makeBrooksCoreyCapPressureTwoPhase2( string const & name, Group & parent ) +{ + BrooksCoreyCapillaryPressure & capPressure = parent.registerGroup< BrooksCoreyCapillaryPressure >( name ); + + string_array & phaseNames = capPressure.getReference< string_array >( CapillaryPressureBase::viewKeyStruct::phaseNamesString() ); + phaseNames.resize( 2 ); + phaseNames[0] = "water"; phaseNames[1] = "gas"; + + array1d< real64 > & phaseMinSat = capPressure.getReference< array1d< real64 > >( BrooksCoreyCapillaryPressure::viewKeyStruct::phaseMinVolumeFractionString() ); + phaseMinSat.resize( 2 ); + phaseMinSat[0] = phase0MinSat2; phaseMinSat[1] = phase1MinSat2; + + array1d< real64 > & phaseCapPressureExpInv = + capPressure.getReference< array1d< real64 > >( BrooksCoreyCapillaryPressure::viewKeyStruct::phaseCapPressureExponentInvString() ); + phaseCapPressureExpInv.resize( 2 ); + phaseCapPressureExpInv[0] = 4; phaseCapPressureExpInv[1] = 1; + + array1d< real64 > & phaseEntryPressure = capPressure.getReference< array1d< real64 > >( BrooksCoreyCapillaryPressure::viewKeyStruct::phaseEntryPressureString() ); + phaseEntryPressure.resize( 2 ); + phaseEntryPressure[0] = 0.5e5; phaseEntryPressure[1] = 0; + + real64 & capPressureEpsilon = capPressure.getReference< real64 >( BrooksCoreyCapillaryPressure::viewKeyStruct::capPressureEpsilonString() ); + capPressureEpsilon = 1e-8; + + capPressure.postInputInitializationRecursive(); + return capPressure; +} + +RelativePermeabilityBase & makeBrooksCoreyRelPerm( string const & name, Group & parent ) +{ + BrooksCoreyRelativePermeability & relPerm = parent.registerGroup< BrooksCoreyRelativePermeability >( name ); + + string_array & phaseNames = relPerm.getReference< string_array >( RelativePermeabilityBase::viewKeyStruct::phaseNamesString() ); + phaseNames.resize( 2 ); + phaseNames[0] = "water"; phaseNames[1] = "gas"; + + array1d< real64 > & phaseMinSat = relPerm.getReference< array1d< real64 > >( BrooksCoreyRelativePermeability::viewKeyStruct::phaseMinVolumeFractionString() ); + phaseMinSat.resize( 2 ); + phaseMinSat[0] = phase0MinSat1; phaseMinSat[1] = phase1MinSat1; + + array1d< real64 > & phaseRelPermExp = relPerm.getReference< array1d< real64 > >( BrooksCoreyRelativePermeability::viewKeyStruct::phaseRelPermExponentString() ); + phaseRelPermExp.resize( 2 ); + phaseRelPermExp[0] = 2.0; phaseRelPermExp[1] = 2.0; + + array1d< real64 > & phaseRelPermMaxVal = relPerm.getReference< array1d< real64 > >( BrooksCoreyRelativePermeability::viewKeyStruct::phaseRelPermMaxValueString() ); + phaseRelPermMaxVal.resize( 2 ); + phaseRelPermMaxVal[0] = 1.0; phaseRelPermMaxVal[1] = 1.0; + + relPerm.postInputInitializationRecursive(); + return relPerm; +} + +class ImmiscibleInterfaceConditionsTest : public FluidModelTest< TwoPhaseImmiscibleFluid, 2 > +{ +public: + ImmiscibleInterfaceConditionsTest(): state( std::make_unique< CommandLineOptions >( g_commandLineOptions )), + m_parent( "TestParentGroup", m_node ) + + {} + +protected: + + static real64 constexpr time = 0.0; + static real64 constexpr dt = 1e4; + static real64 constexpr eps = std::numeric_limits< real64 >::epsilon(); + + GeosxState state; + ImmiscibleMultiphaseFlow *solver; + conduit::Node m_node; + dataRepository::Group m_parent; +}; + +real64 constexpr ImmiscibleInterfaceConditionsTest::time; +real64 constexpr ImmiscibleInterfaceConditionsTest::dt; +real64 constexpr ImmiscibleInterfaceConditionsTest::eps; + + + +TEST_F( ImmiscibleInterfaceConditionsTest, LocalNonlinearSolverConvergence ) +{ + + // using Base = FluidModelTest< TwoPhaseImmiscibleFluid, 2 >; + createFluid( "fluid", [this]( TwoPhaseImmiscibleFluid & fluid ){ + makeTwoPhaseImmiscibleFluid( fluid ); + + // getting constitutive models: + RelativePermeabilityBase & relPerm = makeBrooksCoreyRelPerm( "relPerm" , this->m_parent); + RelativePermeabilityBase * relPermPtr = &relPerm; + // CapillaryPressureBase & capPressure0 = makeJFunctionCapPressureTwoPhase( "capPressure0", this->m_parent ); + // CapillaryPressureBase * capPressurePtr0 = &capPressure0; + + CapillaryPressureBase & capPressure0 = makeTableCapPressureTwoPhase1( "capPressure0", this->m_parent ); + CapillaryPressureBase * capPressurePtr0 = &capPressure0; + + CapillaryPressureBase & capPressure1 = makeTableCapPressureTwoPhase2( "capPressure1", this->m_parent ); + CapillaryPressureBase * capPressurePtr1 = &capPressure1; + // CapillaryPressureBase & capPressure0 = makeBrooksCoreyCapPressureTwoPhase1( "capPressure0", this->m_parent ); + // CapillaryPressureBase * capPressurePtr0 = &capPressure0; + + // CapillaryPressureBase & capPressure1 = makeBrooksCoreyCapPressureTwoPhase2( "capPressure1", this->m_parent ); + // CapillaryPressureBase * capPressurePtr1 = &capPressure1; + + std::vector< RelativePermeabilityBase * > relPerms = {relPermPtr, relPermPtr}; + std::vector< CapillaryPressureBase * > capPressures = {capPressurePtr0, capPressurePtr1}; + std::vector< TwoPhaseImmiscibleFluid * > fluids = { &fluid, &fluid }; + // real64 uT = 3.2864545889999906e-05; + + // real64 uT = -3.3e-5; + real64 uT = 1e-17; +// real64 uT = 1e-7; + stdVector< real64 > saturations = {0.2, 0.4}; + stdVector< real64 > trappedSats1 = {phase0MinSat1, phase1MinSat1}; + stdVector< real64 > trappedSats2 = {phase0MinSat2, phase1MinSat2}; + stdVector< real64 > pressures = {1e7, 1e7}; + stdVector< real64 > JFMultipliers = {45016.662822296035, 30011.108548197357}; + stdVector< real64 > transHats = {1.9738466000000002e-12, 4.4411548500000007e-12}; + stdVector< real64 > dTransHats_dP = {0.0, 0.0}; + stdVector< real64 > gravCoefHats = {490.5, 490.5}; + stdVector< real64 > gravCoefs = {465.97500000000002, 515.02499999999998}; + + + stdVector< real64 > phi = {0.0, 0.0}; + stdVector< real64 > grad_phi = {0.0, 0.0, 0.0, 0.0}; + + std::ofstream outFile( "local_solver_results.csv" ); + + + // Write data to the file + outFile << "Si"; + outFile << ","; + outFile << "Sj"; + outFile << ","; + outFile << "Fw_alpha"; + outFile << ","; + outFile << "Fn_alpha"; + outFile << ","; + outFile << "Residual_initial"; + outFile << ","; + outFile << "Pc_int"; + outFile << ","; + outFile << "Residual"; + outFile << ","; + outFile << "newton"; + outFile << std::endl; + + real64 const start_sat = 0.0; + real64 const end_sat = 1.0; + real64 const dS = 1e-2; + real64 Si = 0.0; + real64 Sj = 0.9; + + // for( real64 Si = start_sat; Si <= end_sat + 1e-8; Si += dS ) + // { + // for( real64 Sj = start_sat; Sj <= end_sat + 1e-8; Sj += dS ) + // { + saturations[0] = Si; + saturations[1] = Sj; + + auto t0 = std::chrono::high_resolution_clock::now(); + +// Call the GEOS local solver + geos::immiscibleMultiphaseKernels::local_solver( uT, saturations, pressures, JFMultipliers, trappedSats1, trappedSats2, transHats, dTransHats_dP, gravCoefHats, gravCoefs, + relPerms, capPressures, fluids, phi, grad_phi ); + +auto t1 = std::chrono::high_resolution_clock::now(); +std::chrono::duration elapsed = t1 - t0; +std::cout << "Local solver time: " << elapsed.count() << " s" << std::endl; + + + // Write data to the file + outFile << GEOS_FMT( "{:10.10e}", saturations[0] ); + outFile << GEOS_FMT( ",{:10.10e}", saturations[1] ); + outFile << GEOS_FMT( ",{:10.10e}", phi[0] ); + outFile << GEOS_FMT( ",{:10.10e}", phi[1] ); + outFile << GEOS_FMT( ",{:10.10e}", grad_phi[0] ); + outFile << GEOS_FMT( ",{:10.10e}", grad_phi[1] ); + outFile << GEOS_FMT( ",{:10.10e}", grad_phi[2] ); + outFile << GEOS_FMT( ",{:10.10e}", grad_phi[3] ); + outFile << std::endl; + phi[0] = 0; + phi[1] = 0; + grad_phi[0] = 0; + grad_phi[1] = 0; + grad_phi[2] = 0; + grad_phi[3] = 0; + +// } +// } + + outFile.close(); + +} ); +} + +int main( int argc, char * *argv ) +{ + ::testing::InitGoogleTest( &argc, argv ); + g_commandLineOptions = *geos::basicSetup( argc, argv ); + int const result = RUN_ALL_TESTS(); + geos::basicCleanup(); + return result; +} + +// maybe needed later on +// TEST_F( CapillaryPressureTest, numericalDerivatives_jFunctionCapPressureTwoPhase ) +// { +// initialize( makeJFunctionCapPressureTwoPhase( "capPressure", m_parent ) ); + +// // here, we have to apply a special treatment to this test +// // to make sure that the J-function multiplier is initialized using initializeRockState +// // this requires calling allocateConstitutiveData in advance (it will be called again later, in the "test" function) + +// // setup some values for porosity and permeability +// array2d< real64 > porosity; +// porosity.resize( 1, 1 ); +// porosity[0][0] = 0.13496794266569806; +// array3d< real64 > permeability; +// permeability.resize( 1, 1, 3 ); +// permeability[0][0][0] = 0.1722194e-15; +// permeability[0][0][1] = 0.3423156e-15; +// permeability[0][0][2] = 0.2324191e-15; + +// // initialize the J-function multiplier (done on GPU if GPU is available) +// m_model->allocateConstitutiveData( m_parent, 1 ); +// m_model->initializeRockState( porosity.toViewConst(), permeability.toViewConst() ); + +// // move the multiplier back to the CPU since the test is performed on the CPU +// auto & jFuncMultiplier = +// m_model->getReference< array2d< real64 > >( fields::cappres::jFuncMultiplier::key() ); +// jFuncMultiplier.move( hostMemorySpace, false ); + +// // we are ready to proceed to the test + +// real64 const eps = std::sqrt( std::numeric_limits< real64 >::epsilon() ); +// real64 const tol = 1e-4; + +// real64 const start_sat = 0.3; +// real64 const end_sat = 0.9; +// real64 const dS = 1e-1; +// array1d< real64 > sat( 2 ); +// sat[0] = start_sat; sat[1] = 1-sat[0]; +// while( sat[0] <= end_sat ) +// { +// test( sat, eps, tol ); +// sat[0] += dS; +// sat[1] = 1 - sat[0]; +// } + +// } \ No newline at end of file diff --git a/src/coreComponents/integrationTests/wellsTests/CMakeLists.txt b/src/coreComponents/integrationTests/wellsTests/CMakeLists.txt index 5a30f2fe376..2a6063f14c2 100644 --- a/src/coreComponents/integrationTests/wellsTests/CMakeLists.txt +++ b/src/coreComponents/integrationTests/wellsTests/CMakeLists.txt @@ -1,6 +1,23 @@ # Specify list of tests set( gtest_geosx_tests +<<<<<<< HEAD:src/coreComponents/unitTests/fluidFlowTests/CMakeLists.txt + testSinglePhaseMobilityKernel.cpp + testThermalCompMultiphaseFlow.cpp + testThermalSinglePhaseFlow.cpp + testFlowStatistics.cpp + testTransmissibility.cpp + testImmiscibleMultiphaseFlow.cpp + testImmiscibleInterfaceConditions.cpp ) + +if( ENABLE_PVTPackage ) + list( APPEND gtest_geosx_tests + testCompMultiphaseFlow.cpp + testCompMultiphaseFlowHybrid.cpp + testReactiveCompositionalMultiphaseOBL.cpp ) +endif() +======= testReservoirSinglePhaseMSWells.cpp ) +>>>>>>> develop:src/coreComponents/integrationTests/wellsTests/CMakeLists.txt set( tplDependencyList ${parallelDeps} gtest ) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp index 624c8960033..00162bb1129 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp @@ -24,12 +24,9 @@ #include "physicsSolvers/PhysicsSolverBaseKernels.hpp" #include "physicsSolvers/fluidFlow/CompositionalMultiphaseUtilities.hpp" #include "physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp" -#include "physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/CapillaryPressureUpdateKernel.hpp" -#include "physicsSolvers/fluidFlow/kernels/compositional/ThermalAccumulationKernel.hpp" #include "physicsSolvers/fluidFlow/kernels/compositional/RelativePermeabilityUpdateKernel.hpp" -#include "constitutive/ConstitutiveManager.hpp" -#include "constitutive/capillaryPressure/CapillaryPressureFields.hpp" -#include "constitutive/capillaryPressure/capillaryPressureSelector.hpp" +#include "physicsSolvers/fluidFlow/kernels/compositional/CapillaryPressureUpdateKernel.hpp" +#include "constitutive/capillaryPressure/CapillaryPressureSelector.hpp" #include "constitutive/relativePermeability/RelativePermeabilitySelector.hpp" #include "fieldSpecification/EquilibriumInitialCondition.hpp" @@ -268,8 +265,7 @@ void ImmiscibleMultiphaseFlow::updateCapPressureModel( ObjectManagerBase & dataG { typename TYPEOFREF( castedCapPres ) ::KernelWrapper capPresWrapper = castedCapPres.createKernelWrapper(); - // isothermalCompositionalMultiphaseBaseKernels:: - immiscibleMultiphaseKernels:: + isothermalCompositionalMultiphaseBaseKernels:: CapillaryPressureUpdateKernel:: launch< parallelDevicePolicy<> >( dataGroup.size(), capPresWrapper, @@ -586,7 +582,7 @@ void ImmiscibleMultiphaseFlow::assembleAccumulationTerm( DomainPartition & domai } void ImmiscibleMultiphaseFlow::assembleFluxTerms( real64 const dt, - DomainPartition & domain, + DomainPartition const & domain, DofManager const & dofManager, CRSMatrixView< real64, globalIndex const > const & localMatrix, arrayView1d< real64 > const & localRhs ) const @@ -599,75 +595,30 @@ void ImmiscibleMultiphaseFlow::assembleFluxTerms( real64 const dt, string const & dofKey = dofManager.getKey( viewKeyStruct::elemDofFieldString() ); - forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&] ( string const &, - MeshLevel & mesh, - string_array const & regionNames ) + MeshLevel const & mesh, + string_array const & ) { - if( m_hasCapPressure ) - { - mesh.getElemManager().forElementSubRegions( regionNames, - [&]( localIndex const, - ElementSubRegionBase & subRegion ) // Check if you need this. - { - // Capillary pressure wrapper - string const & cappresName = subRegion.getReference< string >( viewKeyStruct::capPressureNamesString() ); - JFunctionCapillaryPressure & capPressure = getConstitutiveModel< JFunctionCapillaryPressure >( subRegion, cappresName ); - JFunctionCapillaryPressure::KernelWrapper capPresWrapper = capPressure.createKernelWrapper(); - - // Relative permeability wrapper - string const & relPermName = subRegion.getReference< string >( viewKeyStruct::relPermNamesString() ); - BrooksCoreyRelativePermeability & relPerm = getConstitutiveModel< BrooksCoreyRelativePermeability >( subRegion, relPermName ); - BrooksCoreyRelativePermeability::KernelWrapper relPermWrapper = relPerm.createKernelWrapper(); - - fluxApprox.forAllStencils( mesh, [&]( auto & stencil ) - { - typename TYPEOFREF( stencil ) ::KernelWrapper stencilWrapper = stencil.createKernelWrapper(); - immiscibleMultiphaseKernels:: - FluxComputeKernelFactory::createAndLaunch< parallelDevicePolicy<> >( m_numPhases, - dofManager.rankOffset(), - dofKey, - m_hasCapPressure, - m_useTotalMassEquation, - m_gravityDensityScheme == GravityDensityScheme::PhasePresence, - getName(), - mesh.getElemManager(), - stencilWrapper, - capPresWrapper, - relPermWrapper, - subRegion, - dt, - localMatrix.toViewConstSizes(), - localRhs.toView() ); - } ); - } ); - } - else + fluxApprox.forAllStencils( mesh, [&]( auto & stencil ) { - fluxApprox.forAllStencils( mesh, [&]( auto & stencil ) - { - typename TYPEOFREF( stencil ) ::KernelWrapper stencilWrapper = stencil.createKernelWrapper(); - immiscibleMultiphaseKernels:: + typename TYPEOFREF( stencil ) ::KernelWrapper stencilWrapper = stencil.createKernelWrapper(); + immiscibleMultiphaseKernels:: FluxComputeKernelFactory::createAndLaunch< parallelDevicePolicy<> >( m_numPhases, - dofManager.rankOffset(), - dofKey, - m_hasCapPressure, - m_useTotalMassEquation, - m_gravityDensityScheme == GravityDensityScheme::PhasePresence, - getName(), - mesh.getElemManager(), - stencilWrapper, - dt, - localMatrix.toViewConstSizes(), - localRhs.toView() ); - } ); - } - + dofManager.rankOffset(), + dofKey, + m_hasCapPressure, + m_useTotalMassEquation, + m_gravityDensityScheme == GravityDensityScheme::PhasePresence, + getName(), + mesh.getElemManager(), + stencilWrapper, + dt, + localMatrix.toViewConstSizes(), + localRhs.toView() ); + } ); } ); } -// Ryan: Looks like this will need to be overwritten as well... -// I have left the CompositionalMultiphaseFVM implementation for reference void ImmiscibleMultiphaseFlow::setupDofs( DomainPartition const & domain, DofManager & dofManager ) const { diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp index b1df16899d6..b3769837600 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp @@ -27,6 +27,12 @@ namespace geos { + +namespace constitutive +{ +class ConstitutiveBase; +} // namespace constitutive + //START_SPHINX_INCLUDE_00 /** * @class ImmiscibleMultiphaseFlow @@ -214,6 +220,10 @@ class ImmiscibleMultiphaseFlow : public FlowSolverBase struct viewKeyStruct : public FlowSolverBase::viewKeyStruct { // inputs + static constexpr char const * capPressureNamesString() { return "capPressureNames"; } + static constexpr char const * relPermNamesString() { return "relPermNames"; } + static constexpr char const * elemDofFieldString() { return "elemDofField"; } + static constexpr char const * interfaceFaceSetNamesString() { return "interfaceFaceSetNames"; } // density averaging scheme static constexpr char const * gravityDensitySchemeString() { return "gravityDensityScheme"; } @@ -227,9 +237,9 @@ class ImmiscibleMultiphaseFlow : public FlowSolverBase static constexpr char const * maxRelativePresChangeString() { return "maxRelativePressureChange"; } static constexpr char const * useTotalMassEquationString() { return "useTotalMassEquation"; } - static constexpr char const * capPressureNamesString() { return "capillary_pressure"; } - static constexpr char const * relPermNamesString() { return "relative_permeability"; } - static constexpr char const * elemDofFieldString() { return "elemDofField"; } +// static constexpr char const * capPressureNamesString() { return "capillary_pressure"; } +// static constexpr char const * relPermNamesString() { return "relative_permeability"; } +// static constexpr char const * elemDofFieldString() { return "elemDofField"; } }; @@ -299,6 +309,15 @@ class ImmiscibleMultiphaseFlow : public FlowSolverBase /// damping factor for solution change targets real64 m_solutionChangeScalingFactor; + string_array m_interfaceFaceSetNames; + + stdVector< std::array< std::tuple< constitutive::RelativePermeabilityBase *, + constitutive::CapillaryPressureBase *, + constitutive::TwoPhaseImmiscibleFluid * >, 2 > > m_interfaceConstitutivePairs; + + unordered_map< localIndex, localIndex > m_interfaceRegionByConnector; + unordered_map< localIndex, localIndex > m_connectorIndicesByInterfaceRegion; + private: diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp index a60814d80d9..25399a7ebc8 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp @@ -20,38 +20,47 @@ #ifndef GEOS_PHYSICSSOLVERS_FLUIDFLOW_MULTIPHASEKERNELS_HPP #define GEOS_PHYSICSSOLVERS_FLUIDFLOW_MULTIPHASEKERNELS_HPP -#define Pe_max 5000000.0 -#include "codingUtilities/Utilities.hpp" -#include "common/DataLayouts.hpp" -#include "common/DataTypes.hpp" -#include "common/GEOS_RAJA_Interface.hpp" + + #include "codingUtilities/Utilities.hpp" + #include "common/DataLayouts.hpp" + #include "common/DataTypes.hpp" + #include "common/GEOS_RAJA_Interface.hpp" + #include "constitutive/fluid/twophaseimmisciblefluid/TwoPhaseImmiscibleFluid.hpp" + #include "constitutive/solid/CoupledSolidBase.hpp" + #include "constitutive/fluid/twophaseimmisciblefluid/TwoPhaseImmiscibleFluidFields.hpp" + #include "constitutive/capillaryPressure/CapillaryPressureFields.hpp" + #include "constitutive/capillaryPressure/CapillaryPressureBase.hpp" + #include "constitutive/capillaryPressure/JFunctionCapillaryPressure.hpp" + #include "constitutive/capillaryPressure/TableCapillaryPressure.hpp" + #include "constitutive/permeability/PermeabilityBase.hpp" + #include "constitutive/permeability/PermeabilityFields.hpp" + #include "constitutive/relativePermeability/RelativePermeabilityBase.hpp" + #include "constitutive/relativePermeability/RelativePermeabilityFields.hpp" + #include "constitutive/ConstitutiveManager.hpp" +#include "constitutive/capillaryPressure/capillaryPressureSelector.hpp" +#include "constitutive/relativePermeability/RelativePermeabilitySelector.hpp" + +#include "constitutive/ConstitutivePassThru.hpp" #include "constitutive/fluid/twophaseimmisciblefluid/TwoPhaseImmiscibleFluid.hpp" -#include "constitutive/solid/CoupledSolidBase.hpp" -#include "constitutive/fluid/twophaseimmisciblefluid/TwoPhaseImmiscibleFluidFields.hpp" -#include "constitutive/capillaryPressure/CapillaryPressureFields.hpp" -#include "constitutive/capillaryPressure/CapillaryPressureBase.hpp" -#include "constitutive/capillaryPressure/JFunctionCapillaryPressure.hpp" -#include "constitutive/capillaryPressure/TableCapillaryPressure.hpp" -#include "constitutive/permeability/PermeabilityBase.hpp" -#include "constitutive/permeability/PermeabilityFields.hpp" -#include "constitutive/relativePermeability/RelativePermeabilityBase.hpp" -#include "constitutive/relativePermeability/RelativePermeabilityFields.hpp" -#include "fieldSpecification/AquiferBoundaryCondition.hpp" -#include "finiteVolume/BoundaryStencil.hpp" -#include "finiteVolume/CellElementStencilTPFA.hpp" -#include "finiteVolume/FluxApproximationBase.hpp" -#include "linearAlgebra/interfaces/InterfaceTypes.hpp" -#include "physicsSolvers/PhysicsSolverBaseKernels.hpp" -#include "physicsSolvers/fluidFlow/FlowSolverBaseFields.hpp" -#include "physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlowFields.hpp" -#include "physicsSolvers/fluidFlow/CompositionalMultiphaseUtilities.hpp" -#include "physicsSolvers/fluidFlow/StencilAccessors.hpp" -#include "physicsSolvers/fluidFlow/kernels/compositional/RelativePermeabilityUpdateKernel.hpp" -#include "physicsSolvers/fluidFlow/kernels/compositional/CapillaryPressureUpdateKernel.hpp" -#include "physicsSolvers/PhysicsSolverBaseKernels.hpp" -#include "physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/KernelLaunchSelectors.hpp" -#include "physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/KernelLaunchSelectors.hpp" + + + #include "fieldSpecification/AquiferBoundaryCondition.hpp" + #include "finiteVolume/BoundaryStencil.hpp" + #include "finiteVolume/CellElementStencilTPFA.hpp" + #include "finiteVolume/FluxApproximationBase.hpp" + #include "linearAlgebra/interfaces/InterfaceTypes.hpp" + #include "physicsSolvers/PhysicsSolverBaseKernels.hpp" + #include "physicsSolvers/fluidFlow/FlowSolverBaseFields.hpp" + #include "physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlowFields.hpp" + #include "physicsSolvers/fluidFlow/CompositionalMultiphaseUtilities.hpp" + #include "physicsSolvers/fluidFlow/StencilAccessors.hpp" + #include "physicsSolvers/fluidFlow/kernels/compositional/RelativePermeabilityUpdateKernel.hpp" + #include "physicsSolvers/fluidFlow/kernels/compositional/CapillaryPressureUpdateKernel.hpp" + #include "physicsSolvers/PhysicsSolverBaseKernels.hpp" + #include "physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/KernelLaunchSelectors.hpp" + #include "physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/KernelLaunchSelectors.hpp" + namespace geos { @@ -60,6 +69,1249 @@ namespace immiscibleMultiphaseKernels using namespace constitutive; +GEOS_HOST_DEVICE +inline +static void local_solver( real64 uT, stdVector< real64 > saturations, stdVector< real64 > pressures, stdVector< real64 > JFMultipliers, stdVector< real64 > trappedSats1, + stdVector< real64 > trappedSats2, stdVector< real64 > transHat, stdVector< real64 > dTransHat_dP, stdVector< real64 > gravCoefHat, stdVector< real64 > gravCoef, + stdVector< real64 > cellCenterDuT, stdVector< real64 > cellCenterDens, stdVector< real64 > cellCenterDens_dP, + std::vector< RelativePermeabilityBase * > relPerms, std::vector< CapillaryPressureBase * > capPressures, + std::vector< TwoPhaseImmiscibleFluid * > fluids, std::vector< real64 > &phi, std::vector< real64 > &grad_phi_P, std::vector< real64 > &grad_phi_S, bool &converged ) +{ + + // getting wrappers: + + constitutive::constitutiveUpdatePassThru( *capPressures[0], [&] ( auto & castedCapPres1 ) + { + auto capPresWrapper1 = castedCapPres1.createKernelWrapper(); + + + constitutive::constitutiveUpdatePassThru( *capPressures[1], [&] ( auto & castedCapPres2 ) + { + auto capPresWrapper2 = castedCapPres2.createKernelWrapper(); + + + constitutive::constitutiveUpdatePassThru( *relPerms[0], [&] ( auto & castedRelPerm1 ) + { + auto relPermWrapper1 = castedRelPerm1.createKernelWrapper(); + + + constitutive::constitutiveUpdatePassThru( *relPerms[1], [&] ( auto & castedRelPerm2 ) + { + auto relPermWrapper2 = castedRelPerm2.createKernelWrapper(); + + auto fluidWrapper1 = fluids[0]->createKernelWrapper(); + auto fluidWrapper2 = fluids[1]->createKernelWrapper(); + + // Create an output file stream object (ofstream) for analyzing the local solver's performance + std::ofstream outFile( "iterations2.csv" ); + + + // Write data to the file + outFile << "Jacobian"; + outFile << ","; + outFile << "residual"; + outFile << ","; + outFile << "Fw_alpha"; + outFile << ","; + outFile << "Fw_beta"; + outFile << ","; + outFile << "Pc_int"; + outFile << ","; + outFile << "Pc_int1"; + outFile << ","; + outFile << "Pc_int2"; + outFile << ","; + outFile << "Fn_alpha"; + outFile << ","; + outFile << "Fn_beta"; + outFile << ","; + outFile << "Vw_alpha"; + outFile << ","; + outFile << "Vn_alpha"; + outFile << ","; + outFile << "Vw_beta"; + outFile << ","; + outFile << "Vn_beta"; + outFile << ","; + outFile << "Gw_alpha"; + outFile << ","; + outFile << "Gn_alpha"; + outFile << ","; + outFile << "Gw_beta"; + outFile << ","; + outFile << "Gn_beta"; + outFile << ","; + outFile << "Cw_alpha"; + outFile << ","; + outFile << "Cn_alpha"; + outFile << ","; + outFile << "Cw_beta"; + outFile << ","; + outFile << "Cn_beta"; + outFile << ","; + outFile << "Pc1_ip0"; + outFile << ","; + outFile << "Pc1_ip1"; + outFile << ","; + outFile << "S_alpha"; + outFile << ","; + outFile << "S_beta"; + outFile << std::endl; + + // nonlinear solver's parameters + real64 tol = 1.0e-9; + int max_iter = 50; + converged = 0; + bool damping = true; + bool bisection = false; + bool lineSearch = false; + bool newton_path = false; + + // Local newton loop: + + // Use of the capillary pressure kernel wrapper + + StackArray< real64, 2, 2, immiscibleFlow::LAYOUT_PHASE > phaseVolFrac1( 1, 2 ); + StackArray< real64, 3, 2, constitutive::cappres::LAYOUT_CAPPRES > capPres1( 1, 1, 2 ); + StackArray< real64, 4, 4, constitutive::cappres::LAYOUT_CAPPRES_DS > dPhaseVolFrac_dCapPres1( 1, 1, 2, 2 ); + StackArray< real64, 4, 4, constitutive::cappres::LAYOUT_CAPPRES_DS > dCapPres1_dPhaseVolFrac( 1, 1, 2, 2 ); + StackArray< real64, 2, 2, immiscibleFlow::LAYOUT_PHASE > facePhaseVolFrac1( 1, 2 ); + StackArray< real64, 3, 2, constitutive::cappres::LAYOUT_CAPPRES > faceCapPres1( 1, 1, 2 ); + StackArray< real64, 4, 4, constitutive::cappres::LAYOUT_CAPPRES_DS > dfacePhaseVolFrac_dCapPres1( 1, 1, 2, 2 ); + StackArray< real64, 4, 4, constitutive::cappres::LAYOUT_CAPPRES_DS > dCapPres1_dfacePhaseVolFrac( 1, 1, 2, 2 ); + StackArray< real64, 2, 2, immiscibleFlow::LAYOUT_PHASE > phaseVolFrac2( 1, 2 ); + StackArray< real64, 3, 2, constitutive::cappres::LAYOUT_CAPPRES > capPres2( 1, 1, 2 ); + StackArray< real64, 4, 4, constitutive::cappres::LAYOUT_CAPPRES_DS > dPhaseVolFrac_dCapPres2( 1, 1, 2, 2 ); + StackArray< real64, 4, 4, constitutive::cappres::LAYOUT_CAPPRES_DS > dCapPres2_dPhaseVolFrac( 1, 1, 2, 2 ); + StackArray< real64, 2, 2, immiscibleFlow::LAYOUT_PHASE > facePhaseVolFrac2( 1, 2 ); + StackArray< real64, 3, 2, constitutive::cappres::LAYOUT_CAPPRES > faceCapPres2( 1, 1, 2 ); + StackArray< real64, 4, 4, constitutive::cappres::LAYOUT_CAPPRES_DS > dfacePhaseVolFrac_dCapPres2( 1, 1, 2, 2 ); + StackArray< real64, 4, 4, constitutive::cappres::LAYOUT_CAPPRES_DS > dCapPres2_dfacePhaseVolFrac( 1, 1, 2, 2 ); + StackArray< real64, 1, 2 > JFunc1( 2 ); + StackArray< real64, 1, 2 > JFunc2( 2 ); + + phaseVolFrac1[0][0] = saturations[0]; + phaseVolFrac1[0][1] = 1.0 - saturations[0]; + + phaseVolFrac2[0][0] = saturations[1]; + phaseVolFrac2[0][1] = 1.0 - saturations[1]; + + real64 Pc1_min = 0.0; + real64 Pc2_min = 0.0; + real64 Pc1_max = 0.0; + real64 Pc2_max = 0.0; + + real64 density2[2]{}; + real64 dDens_dP2[2][2]{}; + + density2[0] = cellCenterDens[0]; + density2[1] = cellCenterDens[1]; + + dDens_dP2[0][0] = cellCenterDens_dP[0]; + dDens_dP2[0][1] = cellCenterDens_dP[1]; + dDens_dP2[1][0] = cellCenterDens_dP[2]; + dDens_dP2[1][1] = cellCenterDens_dP[3]; + + JFunc1[0] = JFMultipliers[0]; + JFunc2[0] = JFMultipliers[1]; + + using T1 = std::decay_t< decltype(castedCapPres1) >; + if constexpr (std::is_same_v< T1, JFunctionCapillaryPressure >) { + capPresWrapper1.compute( phaseVolFrac1[0], + JFunc1.toSliceConst(), + capPres1[0][0], + dCapPres1_dPhaseVolFrac[0][0] ); + + facePhaseVolFrac1[0][1] = 0.0; + facePhaseVolFrac1[0][0] = 1.0; + capPresWrapper1.compute( facePhaseVolFrac1[0], + JFunc1.toSliceConst(), + faceCapPres1[0][0], + dCapPres1_dfacePhaseVolFrac[0][0] ); + Pc1_min = faceCapPres1[0][0][0]; + facePhaseVolFrac1[0][1] = 1.0; + facePhaseVolFrac1[0][0] = 0.0; + capPresWrapper1.compute( facePhaseVolFrac1[0], + JFunc1.toSliceConst(), + faceCapPres1[0][0], + dCapPres1_dfacePhaseVolFrac[0][0] ); + Pc1_max = faceCapPres1[0][0][0]; + + } + else + { + capPresWrapper1.compute( phaseVolFrac1[0], + capPres1[0][0], + dCapPres1_dPhaseVolFrac[0][0] ); + + facePhaseVolFrac1[0][1] = 0.0; + facePhaseVolFrac1[0][0] = 1.0; + capPresWrapper1.compute( facePhaseVolFrac1[0], + faceCapPres1[0][0], + dCapPres1_dfacePhaseVolFrac[0][0] ); + Pc1_min = faceCapPres1[0][0][0]; + facePhaseVolFrac1[0][1] = 1.0; + facePhaseVolFrac1[0][0] = 0.0; + capPresWrapper1.compute( facePhaseVolFrac1[0], + faceCapPres1[0][0], + dCapPres1_dfacePhaseVolFrac[0][0] ); + Pc1_max = faceCapPres1[0][0][0]; + } + + using T2 = std::decay_t< decltype(castedCapPres2) >; + if constexpr (std::is_same_v< T2, JFunctionCapillaryPressure >) { + // evaluating cell-center Pc: + + capPresWrapper2.compute( phaseVolFrac2[0], + JFunc2.toSliceConst(), + capPres2[0][0], + dCapPres2_dPhaseVolFrac[0][0] ); + +// finding endpoints: + + facePhaseVolFrac2[0][1] = 0.0; + facePhaseVolFrac2[0][0] = 1.0; + capPresWrapper2.compute( facePhaseVolFrac2[0], + JFunc2.toSliceConst(), + faceCapPres2[0][0], + dCapPres2_dfacePhaseVolFrac[0][0] ); + Pc2_min = faceCapPres2[0][0][0]; + facePhaseVolFrac2[0][1] = 1.0; + facePhaseVolFrac2[0][0] = 0.0; + capPresWrapper2.compute( facePhaseVolFrac2[0], + JFunc2.toSliceConst(), + faceCapPres2[0][0], + dCapPres2_dfacePhaseVolFrac[0][0] ); + Pc2_max = faceCapPres2[0][0][0]; + + } + else + { + // evaluating cell-center Pc: + + capPresWrapper2.compute( phaseVolFrac2[0], + capPres2[0][0], + dCapPres2_dPhaseVolFrac[0][0] ); + +// finding endpoints: + + facePhaseVolFrac2[0][1] = 0.0; + facePhaseVolFrac2[0][0] = 1.0; + capPresWrapper2.compute( facePhaseVolFrac2[0], + faceCapPres2[0][0], + dCapPres2_dfacePhaseVolFrac[0][0] ); + Pc2_min = faceCapPres2[0][0][0]; + facePhaseVolFrac2[0][1] = 1.0; + facePhaseVolFrac2[0][0] = 0.0; + capPresWrapper2.compute( facePhaseVolFrac2[0], + faceCapPres2[0][0], + dCapPres2_dfacePhaseVolFrac[0][0] ); + Pc2_max = faceCapPres2[0][0][0]; + } + + // Use of the relative permeability kernel wrapper + + StackArray< real64, 3, 2, constitutive::relperm::LAYOUT_RELPERM > faceTrappedVolFrac1( 1, 1, 2 ); + StackArray< real64, 3, 2, constitutive::relperm::LAYOUT_RELPERM > faceRelPerm1( 1, 1, 2 ); + StackArray< real64, 4, 4, constitutive::relperm::LAYOUT_RELPERM_DS > dfacePhaseRelPerm1_dPhaseVolFrac( 1, 1, 2, 2 ); + StackArray< real64, 3, 2, constitutive::relperm::LAYOUT_RELPERM > trappedVolFrac1( 1, 1, 2 ); + StackArray< real64, 3, 2, constitutive::relperm::LAYOUT_RELPERM > relPerm1( 1, 1, 2 ); + StackArray< real64, 4, 4, constitutive::relperm::LAYOUT_RELPERM_DS > dPhaseRelPerm1_dPhaseVolFrac( 1, 1, 2, 2 ); + StackArray< real64, 3, 2, constitutive::relperm::LAYOUT_RELPERM > faceTrappedVolFrac2( 1, 1, 2 ); + StackArray< real64, 3, 2, constitutive::relperm::LAYOUT_RELPERM > faceRelPerm2( 1, 1, 2 ); + StackArray< real64, 4, 4, constitutive::relperm::LAYOUT_RELPERM_DS > dfacePhaseRelPerm2_dPhaseVolFrac( 1, 1, 2, 2 ); + StackArray< real64, 3, 2, constitutive::relperm::LAYOUT_RELPERM > trappedVolFrac2( 1, 1, 2 ); + StackArray< real64, 3, 2, constitutive::relperm::LAYOUT_RELPERM > relPerm2( 1, 1, 2 ); + StackArray< real64, 4, 4, constitutive::relperm::LAYOUT_RELPERM_DS > dPhaseRelPerm2_dPhaseVolFrac( 1, 1, 2, 2 ); + + StackArray< real64, 2, 2, immiscibleFlow::LAYOUT_PHASE > phaseMaxHistoricalVolFraction1( 1, 2 ); + StackArray< real64, 2, 2, immiscibleFlow::LAYOUT_PHASE > phaseMinHistoricalVolFraction1( 1, 2 ); + StackArray< real64, 2, 2, immiscibleFlow::LAYOUT_PHASE > phaseMaxHistoricalVolFraction2( 1, 2 ); + StackArray< real64, 2, 2, immiscibleFlow::LAYOUT_PHASE > phaseMinHistoricalVolFraction2( 1, 2 ); + + // compute relative permeability for both cell centers: + + trappedVolFrac1[0][0][0] = trappedSats1[0]; + trappedVolFrac1[0][0][1] = trappedSats1[1]; + + trappedVolFrac2[0][0][0] = trappedSats2[0]; + trappedVolFrac2[0][0][1] = trappedSats2[1]; + + faceTrappedVolFrac1[0][0][0] = trappedSats1[0]; + faceTrappedVolFrac1[0][0][1] = trappedSats1[1]; + + faceTrappedVolFrac2[0][0][0] = trappedSats2[0]; + faceTrappedVolFrac2[0][0][1] = trappedSats2[1]; + + using T5 = std::decay_t< decltype(castedRelPerm1) >; + if constexpr (std::is_same_v< T5, constitutive::TableRelativePermeabilityHysteresis >) { + relPermWrapper1.compute( phaseVolFrac1[0], + phaseMaxHistoricalVolFraction1[0], + phaseMinHistoricalVolFraction1[0], + trappedVolFrac1[0][0], + relPerm1[0][0], + dPhaseRelPerm1_dPhaseVolFrac[0][0] ); + + } + else + { + + relPermWrapper1.compute( phaseVolFrac1[0], + trappedVolFrac1[0][0], + relPerm1[0][0], + dPhaseRelPerm1_dPhaseVolFrac[0][0] ); + } + + using T6 = std::decay_t< decltype(castedRelPerm2) >; + if constexpr (std::is_same_v< T6, constitutive::TableRelativePermeabilityHysteresis >) { + relPermWrapper2.compute( phaseVolFrac2[0], + phaseMaxHistoricalVolFraction2[0], + phaseMinHistoricalVolFraction2[0], + trappedVolFrac2[0][0], + relPerm2[0][0], + dPhaseRelPerm2_dPhaseVolFrac[0][0] ); + + } + else + { + + relPermWrapper2.compute( phaseVolFrac2[0], + trappedVolFrac2[0][0], + relPerm2[0][0], + dPhaseRelPerm2_dPhaseVolFrac[0][0] ); + } + + + // Use of the fluid model kernel wrapper + StackArray< real64, 3, 2, constitutive::multifluid::LAYOUT_PHASE > phaseDensity1( 1, 1, 2 ); + StackArray< real64, 3, 2, constitutive::multifluid::LAYOUT_PHASE > phaseViscosity1( 1, 1, 2 ); + StackArray< real64, 4, 4, constitutive::multifluid::LAYOUT_PHASE_DC > dPhaseDens1_dP( 1, 1, 2, 2 ); + StackArray< real64, 4, 4, constitutive::multifluid::LAYOUT_PHASE_DC > dPhaseVisc1_dP( 1, 1, 2, 2 ); + StackArray< real64, 3, 2, constitutive::multifluid::LAYOUT_PHASE > phaseDensity2( 1, 1, 2 ); + StackArray< real64, 3, 2, constitutive::multifluid::LAYOUT_PHASE > phaseViscosity2( 1, 1, 2 ); + StackArray< real64, 4, 4, constitutive::multifluid::LAYOUT_PHASE_DC > dPhaseDens2_dP( 1, 1, 2, 2 ); + StackArray< real64, 4, 4, constitutive::multifluid::LAYOUT_PHASE_DC > dPhaseVisc2_dP( 1, 1, 2, 2 ); + + // Declare the MultiFluidVar (PhaseProp) type + TwoPhaseImmiscibleFluid::PhaseProp phaseDensity_temp1; + TwoPhaseImmiscibleFluid::PhaseProp phaseViscosity_temp1; + phaseDensity_temp1.value.resize( 1, 1, 2 ); // or whatever sizes you need + phaseDensity_temp1.derivs.resize( 1, 1, 2, 2 ); // make sure all dims > 0 + phaseViscosity_temp1.value.resize( 1, 1, 2 ); // or whatever sizes you need + phaseViscosity_temp1.derivs.resize( 1, 1, 2, 2 ); // make sure all dims > 0 + + auto phaseDensitySlice0 = TwoPhaseImmiscibleFluid::PhaseProp::SliceType( + phaseDensity_temp1.value[0][0], phaseDensity_temp1.derivs[0][0] ); + auto phaseViscositySlice0 = TwoPhaseImmiscibleFluid::PhaseProp::SliceType( + phaseViscosity_temp1.value[0][0], phaseViscosity_temp1.derivs[0][0] ); + fluidWrapper1.compute( pressures[0], phaseDensitySlice0, phaseViscositySlice0 ); + + // Temporary: + phaseDensity1[0][0][0] = phaseDensitySlice0.value[0]; + phaseDensity1[0][0][1] = phaseDensitySlice0.value[1]; + dPhaseDens1_dP[0][0][0][0] = phaseDensitySlice0.derivs[0][0]; + dPhaseDens1_dP[0][0][0][1] = 0; + dPhaseDens1_dP[0][0][1][0] = phaseDensitySlice0.derivs[1][0]; + dPhaseDens1_dP[0][0][1][1] = 0; + + phaseViscosity1[0][0][0] = phaseViscositySlice0.value[0]; + phaseViscosity1[0][0][1] = phaseViscositySlice0.value[1]; + dPhaseVisc1_dP[0][0][0][0] = phaseViscositySlice0.derivs[0][0]; + dPhaseVisc1_dP[0][0][0][1] = 0; + dPhaseVisc1_dP[0][0][1][0] = phaseViscositySlice0.derivs[1][0]; + dPhaseVisc1_dP[0][0][1][1] = 0; + + auto phaseDensitySlice1 = TwoPhaseImmiscibleFluid::PhaseProp::SliceType( + phaseDensity_temp1.value[0][0], phaseDensity_temp1.derivs[0][0] ); + auto phaseViscositySlice1 = TwoPhaseImmiscibleFluid::PhaseProp::SliceType( + phaseViscosity_temp1.value[0][0], phaseViscosity_temp1.derivs[0][0] ); + fluidWrapper2.compute( pressures[1], phaseDensitySlice1, phaseViscositySlice1 ); + + + phaseDensity2[0][0][0] = phaseDensitySlice1.value[0]; + phaseDensity2[0][0][1] = phaseDensitySlice1.value[1]; + dPhaseDens2_dP[0][0][0][0] = phaseDensitySlice1.derivs[0][0]; + dPhaseDens2_dP[0][0][0][1] = 0; + dPhaseDens2_dP[0][0][1][0] = phaseDensitySlice1.derivs[1][0]; + dPhaseDens2_dP[0][0][1][1] = 0; + + phaseViscosity2[0][0][0] = phaseViscositySlice1.value[0]; + phaseViscosity2[0][0][1] = phaseViscositySlice1.value[1]; + dPhaseVisc2_dP[0][0][0][0] = phaseViscositySlice1.derivs[0][0]; + dPhaseVisc2_dP[0][0][0][1] = 0; + dPhaseVisc2_dP[0][0][1][0] = phaseViscositySlice1.derivs[1][0]; + dPhaseVisc2_dP[0][0][1][1] = 0; + + // clear working arrays + real64 halfFluxVal[2][2]{}; + real64 dhalfFlux1_dP[2][2]{}; + real64 dhalfFlux1_dS[2][2]{}; + real64 dhalfFlux2_dP[2][2]{}; + real64 dhalfFlux2_dS[2][2]{}; + real64 dhalfFlux_duT[2][2]{}; + real64 dhalfFlux_dpc[2][2]{}; + + //new + real64 fluxVal[2]{}; + real64 dFlux_dP[2][2]{}; + real64 dFlux_dS[2][2]{}; + + real64 duT_dP[2]{}; + real64 duT_dS[2]{}; + + duT_dP[0] = cellCenterDuT[0]; + duT_dP[1] = cellCenterDuT[1]; + + duT_dS[0] = cellCenterDuT[2]; + duT_dS[1] = cellCenterDuT[3]; + + // initial guess: + + real64 const Pc1 = capPres1[0][0][0]; + real64 const Pc2 = capPres2[0][0][0]; + + real64 Pc_int = ( Pc1 + Pc2 ) / 2.0; + + real64 Pc_min_all = fmax( Pc1_min, Pc2_min ); + real64 Pc_max_all = fmin( Pc1_max, Pc2_max ); + + if( Pc_int < Pc_min_all || Pc_int > Pc_max_all ) + { + Pc_int = ( Pc_min_all + Pc_max_all ) / 2.0; + } + + // While loop (newton loop) + int iter = 0; + int div = 0; + int ext_iter0 = 0; + int ext_iter1 = 0; + real64 next_Pc_int = 0.0; + real64 old_Pc_int = 0.0; + real64 old_residual = 0.0; + + if (bisection) { + Pc_int = fmax( Pc1_max, Pc2_max ); + next_Pc_int = fmin( Pc1_min, Pc2_min ); + } + + if (newton_path){ + Pc_int = fmax( Pc1_max, Pc2_max ); + Pc_int = 2.0e5; + next_Pc_int = (fmax( Pc1_max, Pc2_max ) - fmin( Pc1_min, Pc2_min )) / (max_iter - 1); + next_Pc_int = (2.0e5 - 5.0e4) / (max_iter - 1); + } + + real64 Pc_int_iterate = Pc_int; + + while( iter < max_iter ) + { + + Pc_int_iterate = Pc_int; + + // clear working arrays + real64 density[2]{}; + real64 dDens_dP[2][2]{}; + real64 gravityCof[2]{}; + real64 viscosity[2]{}; + real64 dVisc_dP[2][2]{}; + + real64 viscous[2][2]{}; + real64 bouyancy[2][2]{}; + real64 capillarity[2][2]{}; + + real64 dV1_dS[2][2]{}; + real64 dG1_dS[2][2]{}; + real64 dC1_dS[2][2]{}; + real64 dV2_dS[2][2]{}; + real64 dG2_dS[2][2]{}; + real64 dC2_dS[2][2]{}; + real64 dV1_dpc[2][2]{}; + real64 dG1_dpc[2][2]{}; + real64 dC1_dpc[2][2]{}; + real64 dV2_dpc[2][2]{}; + real64 dG2_dpc[2][2]{}; + real64 dC2_dpc[2][2]{}; + + real64 local_residual = 0; + real64 local_jacobian = 0; + + // truncate the capillary pressure iterate (ensures the inverse will compute a saturation bounded between 0 and 1): + + Pc_int = fmin( fmax( Pc1_max, Pc2_max ), fmax( Pc_int, fmin( Pc1_min, Pc2_min ) )); + + faceCapPres1[0][0][0] = fmin( Pc1_max, fmax( Pc_int, Pc1_min)); + faceCapPres2[0][0][0] = fmin( Pc2_max, fmax( Pc_int, Pc2_min)); + + // Compute the inverse: + + JFunc1[0] = JFMultipliers[0]; + JFunc2[0] = JFMultipliers[1]; + + using T3 = std::decay_t< decltype(castedCapPres1) >; + if constexpr (std::is_same_v< T3, JFunctionCapillaryPressure >) { + capPresWrapper1.computeInv( facePhaseVolFrac1[0], + JFunc1.toSliceConst(), + faceCapPres1[0][0], + dfacePhaseVolFrac_dCapPres1[0][0] ); + facePhaseVolFrac1[0][0] = fmin( 1.0, fmax( facePhaseVolFrac1[0][0], 0.0 )); + facePhaseVolFrac1[0][1] = fmin( 1.0, fmax( facePhaseVolFrac1[0][1], 0.0 )); + //get derivatives: + capPresWrapper1.compute( facePhaseVolFrac1[0], + JFunc1.toSliceConst(), + faceCapPres1[0][0], + dCapPres1_dfacePhaseVolFrac[0][0] ); + + } + else + { + capPresWrapper1.computeInv( facePhaseVolFrac1[0], + faceCapPres1[0][0], + dfacePhaseVolFrac_dCapPres1[0][0] ); + facePhaseVolFrac1[0][0] = fmin( 1.0, fmax( facePhaseVolFrac1[0][0], 0.0 )); + facePhaseVolFrac1[0][1] = fmin( 1.0, fmax( facePhaseVolFrac1[0][1], 0.0 )); + //get derivatives: + capPresWrapper1.compute( facePhaseVolFrac1[0], + faceCapPres1[0][0], + dCapPres1_dfacePhaseVolFrac[0][0] ); + } + + using T4 = std::decay_t< decltype(castedCapPres2) >; + if constexpr (std::is_same_v< T4, JFunctionCapillaryPressure >) { + // evaluating cell-center Pc: + capPresWrapper2.computeInv( facePhaseVolFrac2[0], + JFunc2.toSliceConst(), + faceCapPres2[0][0], + dfacePhaseVolFrac_dCapPres2[0][0] ); + facePhaseVolFrac2[0][0] = fmin( 1.0, fmax( facePhaseVolFrac2[0][0], 0.0 )); + facePhaseVolFrac2[0][1] = fmin( 1.0, fmax( facePhaseVolFrac2[0][1], 0.0 )); + +//get derivatives: + + capPresWrapper2.compute( facePhaseVolFrac2[0], + JFunc2.toSliceConst(), + faceCapPres2[0][0], + dCapPres2_dfacePhaseVolFrac[0][0] ); + + } + else + { + // evaluating cell-center Pc: + capPresWrapper2.computeInv( facePhaseVolFrac2[0], + faceCapPres2[0][0], + dfacePhaseVolFrac_dCapPres2[0][0] ); + facePhaseVolFrac2[0][0] = fmin( 1.0, fmax( facePhaseVolFrac2[0][0], 0.0 )); + facePhaseVolFrac2[0][1] = fmin( 1.0, fmax( facePhaseVolFrac2[0][1], 0.0 )); + +//get derivatives: + + capPresWrapper2.compute( facePhaseVolFrac2[0], + faceCapPres2[0][0], + dCapPres2_dfacePhaseVolFrac[0][0] ); + } + + // compute relative permeability for both faces: + + using T7 = std::decay_t< decltype(castedRelPerm1) >; + if constexpr (std::is_same_v< T7, constitutive::TableRelativePermeabilityHysteresis >) { + + relPermWrapper1.compute( facePhaseVolFrac1[0], + phaseMaxHistoricalVolFraction1[0], + phaseMinHistoricalVolFraction1[0], + faceTrappedVolFrac1[0][0], + faceRelPerm1[0][0], + dfacePhaseRelPerm1_dPhaseVolFrac[0][0] ); + + } + else + { + + relPermWrapper1.compute( facePhaseVolFrac1[0], + faceTrappedVolFrac1[0][0], + faceRelPerm1[0][0], + dfacePhaseRelPerm1_dPhaseVolFrac[0][0] ); + } + + using T8 = std::decay_t< decltype(castedRelPerm2) >; + if constexpr (std::is_same_v< T8, constitutive::TableRelativePermeabilityHysteresis >) { + + relPermWrapper2.compute( facePhaseVolFrac2[0], + phaseMaxHistoricalVolFraction2[0], + phaseMinHistoricalVolFraction2[0], + faceTrappedVolFrac2[0][0], + faceRelPerm2[0][0], + dfacePhaseRelPerm2_dPhaseVolFrac[0][0] ); + + } + else + { + + relPermWrapper2.compute( facePhaseVolFrac2[0], + faceTrappedVolFrac2[0][0], + faceRelPerm2[0][0], + dfacePhaseRelPerm2_dPhaseVolFrac[0][0] ); + } + + + // Brenier and Jaffre's PPU upwinding: + bool check = false; + bool k_up_0_w = 1; + bool k_up_1_w = 1; + bool k_up_0_n = 1; + bool k_up_1_n = 1; + + if( uT < 0.0 ) + { + k_up_0_w = 0; + k_up_1_w = 0; + k_up_0_n = 0; + k_up_1_n = 0; + } + + if( std::fabs( uT ) < 1e-20 ) + { + k_up_0_w = 1; + k_up_1_w = 1; + k_up_0_n = 0; + k_up_1_n = 0; + } + + + localIndex k_up_0[2] = {static_cast< localIndex >(!k_up_0_w), static_cast< localIndex >(!k_up_0_n)}; + localIndex k_up_1[2] = {static_cast< localIndex >(k_up_1_w), static_cast< localIndex >(k_up_1_n)}; + bool k_up_0_check[2] = {false, false}; + bool k_up_1_check[2] = {false, false}; + + while( !check ) + { + k_up_0_check[0] = false; + k_up_0_check[1] = false; + k_up_1_check[0] = false; + k_up_1_check[1] = false; + for( integer ix = 0; ix < 2; ++ix ) // for loop over each half flux + { + + // clear working arrays for each half flux: + real64 densMean[2]{}; + real64 dDensMean_dP[2][2]{}; + + real64 presGrad[2]{}; + real64 dPresGrad_dP[2][2]{}; + + real64 gravHead[2]{}; + real64 dGravHead_dP[2][2]{}; + + real64 capGrad[2]{}; + real64 capPresIC[2][2]{}; + real64 jFMultiplier[2][2]{}; + real64 dCapGrad_dP[2][2]{}; + real64 dCapGrad_dS[2][2]{}; + + real64 mobility[2]{}; + real64 dMob_dP[2][2]{}; + real64 dMob_dS[2][2]{}; + + real64 total_mobility = 0; + gravityCof[0] = 0; + gravityCof[1] = 0; + + for( integer ip = 0; ip < 2; ++ip ) // loop over phases + { + // calculate quantities on primary connected cells + if( ix == 0 ) + { + density[ip] = phaseDensity1[0][0][ip]; + dDens_dP[ip][ix] = dPhaseDens1_dP[0][0][ip][ip]; + + viscosity[ip] = phaseViscosity1[0][0][ip]; + dVisc_dP[ip][ix] = dPhaseVisc1_dP[0][0][ip][ip]; + } + else + { + density[ip] = phaseDensity2[0][0][ip]; + dDens_dP[ip][ix] = dPhaseDens2_dP[0][0][ip][ip]; + + viscosity[ip] = phaseViscosity2[0][0][ip]; + dVisc_dP[ip][ix] = dPhaseVisc2_dP[0][0][ip][ip]; + } + + densMean[ip] = density[ip]; + dDensMean_dP[ip][0] = dDens_dP[ip][ix]; + dDensMean_dP[ip][1] = dDens_dP[ip][ix]; + + //***** calculation of flux ***** + + // compute potential difference + real64 potScale = 0.0; + real64 dPresGrad_dTrans = 0.0; + real64 dGravHead_dTrans = 0.0; + real64 dCapGrad_dTrans = 0.0; + constexpr int signPotDiff[2] = {1, -1}; + constexpr int signTix[2] = {1, -1}; + + for( integer ke = 0; ke < 2; ++ke ) + { + + real64 const pressure = pressures[ix]; + presGrad[ip] += signTix[ke] * transHat[ix] * pressure; + dPresGrad_dTrans += signPotDiff[ke] * pressure; + dPresGrad_dP[ip][ke] = signTix[ke] * transHat[ix]; + + real64 gravD = 0.0; + + if( ke == 0 ) + { + gravD += signTix[ke] * transHat[ix] * gravCoef[ix]; + } + else + { + gravD += signTix[ke] * transHat[ix] * gravCoefHat[ix]; + } + + real64 pot = signTix[ke] * transHat[ix] * pressure - densMean[ip] * gravD; + + gravHead[ip] += densMean[ip] * gravD; + gravityCof[ip] += gravD; + + dGravHead_dTrans += signPotDiff[ke] * densMean[ip] * gravCoefHat[ix]; + + for( integer i = 0; i < 2; ++i ) + { + dGravHead_dP[ip][i] += dDensMean_dP[ip][i] * gravD; + } + + real64 capPres = capPres1[0][0][ip]; + + if( ke == 1 && ix == 0 ) + { + capPres = faceCapPres1[0][0][ip]; + } + else if( ke == 1 && ix == 1 ) + { + capPres = faceCapPres2[0][0][ip]; + } + else if( ke == 0 && ix == 1 ) + { + + capPres = capPres2[0][0][ip]; + } + + dCapGrad_dTrans -= signPotDiff[ke] * capPres; + pot -= signTix[ke] * transHat[ix] * capPres; + + capGrad[ip] -= signTix[ke] * transHat[ix] * capPres; + + potScale = fmax( potScale, fabs( pot ) ); + } + + for( integer ke = 0; ke < 2; ++ke ) + { + dPresGrad_dP[ip][ke] += signTix[ke] * dTransHat_dP[ix] * dPresGrad_dTrans; + + dGravHead_dP[ip][ke] += signTix[ke] * dTransHat_dP[ix] * dGravHead_dTrans; + + real64 constexpr eps = 1e-18; + real64 dCapPres_dS = dCapPres1_dPhaseVolFrac[0][0][ip][ip]; + + if( ke == 1 && ix == 0 ) + { + dCapPres_dS = dCapPres1_dfacePhaseVolFrac[0][0][ip][ip]; + } + else if( ke == 1 && ix == 1 ) + { + dCapPres_dS = dCapPres2_dfacePhaseVolFrac[0][0][ip][ip]; + } + else if( ke == 0 && ix == 1 ) + { + dCapPres_dS = dCapPres2_dPhaseVolFrac[0][0][ip][ip]; + } + + dCapGrad_dP[ip][ke] += signTix[ke] * dTransHat_dP[ix] * dCapGrad_dTrans; + dCapGrad_dS[ip][ke] -= signTix[ke] * transHat[ix] * dCapPres_dS; + } + + // *** upwinding *** + // compute potential gradient + real64 potGrad = presGrad[ip] - gravHead[ip]; + + potGrad += capGrad[ip]; + + // choose upstream cell + constexpr int sign[2] = {1, -1}; + + if( k_up_0[ip] == 1 && ix == 0 ) + { + mobility[ip] = faceRelPerm1[0][0][ip] / viscosity[ip]; + dMob_dP[ip][k_up_0[ip]] = mobility[ip] * (-dVisc_dP[ip][ix] / viscosity[ip]); + + dMob_dS[ip][k_up_0[ip]] = sign[ip] * dfacePhaseRelPerm1_dPhaseVolFrac[0][0][ip][ip] / viscosity[ip]; + } + else if( k_up_1[ip] == 0 && ix == 1 ) + { + mobility[ip] = relPerm2[0][0][ip] / viscosity[ip]; + dMob_dP[ip][0] = mobility[ip] * (-dVisc_dP[ip][ix] / viscosity[ip]); + dMob_dS[ip][0] = sign[ip] * dPhaseRelPerm2_dPhaseVolFrac[0][0][ip][ip] / viscosity[ip]; + } + else if( k_up_1[ip] == 1 && ix == 1 ) + { + mobility[ip] = faceRelPerm2[0][0][ip] / viscosity[ip]; + dMob_dP[ip][1] = mobility[ip] * (-dVisc_dP[ip][ix] / viscosity[ip]); + dMob_dS[ip][1] = sign[ip] * dfacePhaseRelPerm2_dPhaseVolFrac[0][0][ip][ip] / viscosity[ip]; + } + else + { + mobility[ip] = relPerm1[0][0][ip] / viscosity[ip]; + dMob_dP[ip][ix] = mobility[ip] * (-dVisc_dP[ip][ix] / viscosity[ip]); + dMob_dS[ip][ix] = sign[ip] * dPhaseRelPerm1_dPhaseVolFrac[0][0][ip][ip] / viscosity[ip]; + } + real64 constexpr eps = 0.0; + total_mobility += mobility[ip] + eps; + } // loop over phases + + /// Three Forces Flux Contribution: 1- Viscous 2- Gravitational 3- Capillary + constexpr int sign[2] = {1, -1}; + real64 constexpr eps = 0.0; + + // loop over phases + for( integer ip = 0; ip < 2; ++ip ) + { + // 1- Viscous: pressure gradient depends on all points in the stencil + viscous[ip][ix] = mobility[ip] / total_mobility * uT; + halfFluxVal[ip][ix] = viscous[ip][ix]; + + for( integer ke = 0; ke < 2; ++ke ) + { + real64 dV_dP = sign[ip] * (dMob_dP[0][ke] * mobility[1] - dMob_dP[1][ke] * mobility[0]) / (total_mobility * total_mobility) * uT; + real64 dV_dS = sign[ip] * (dMob_dS[0][ke] * mobility[1] - dMob_dS[1][ke] * mobility[0]) / (total_mobility * total_mobility) * uT; + real64 dV_du = mobility[ip] / total_mobility; + + if( ix == 0 ) + { + dV1_dS[ip][ke] = dV_dS; + dhalfFlux1_dP[ip][ke] = dV_dP; + dhalfFlux1_dS[ip][ke] = dV1_dS[ip][ke]; + dhalfFlux_duT[ip][ix] = dV_du; + dV1_dpc[ip][ke] = dV1_dS[ip][ke] * dfacePhaseVolFrac_dCapPres1[0][0][0][0]; + // GEOS_UNUSED_VAR( dV1_dpc[ip][ke] ); + GEOS_UNUSED_VAR( dhalfFlux_duT[ip][ix] ); + } + else + { + dV2_dS[ip][ke] = dV_dS; + dhalfFlux2_dP[ip][ke] = dV_dP; + dhalfFlux2_dS[ip][ke] = dV2_dS[ip][ke]; + dhalfFlux_duT[ip][ix]= dV_du; + dV2_dpc[ip][ke] = dV2_dS[ip][ke] * dfacePhaseVolFrac_dCapPres2[0][0][0][0]; + // GEOS_UNUSED_VAR( dV2_dpc[ip][ke] ); + GEOS_UNUSED_VAR( dhalfFlux_duT[ip][ix] ); + } + } + + // 2- Gravitational: gravitational head depends only on the two cells connected (same as mean density) + bouyancy[ip][ix] = -1.0 * sign[ix] * sign[ip] * mobility[0] * mobility[1] / total_mobility * gravityCof[0] * (density[0] - density[1]); + halfFluxVal[ip][ix] += bouyancy[ip][ix]; + + for( integer ke = 0; ke < 2; ++ke ) + { + real64 dG_dP = sign[ix] * sign[ip] * (dMob_dP[0][ke] * mobility[1] * mobility[1] + dMob_dP[1][ke] * mobility[0] * mobility[0]) / (total_mobility * total_mobility) * gravityCof[0] * + (density[0] - density[1]) + + sign[ix] * (mobility[0] * mobility[1]) / total_mobility * (dDens_dP[0][ix] - dDens_dP[1][ix]); + + real64 dG_dS = sign[ix] * sign[ip] * (dMob_dS[0][ke] * mobility[1] * mobility[1] + dMob_dS[1][ke] * mobility[0] * mobility[0]) / (total_mobility * total_mobility) * + gravityCof[0] * (density[0] - density[1]); + + if( ix == 0 ) + { + dG1_dS[ip][ke] = dG_dS; + dhalfFlux1_dP[ip][ke] -= dG_dP; + dhalfFlux1_dS[ip][ke] -= dG1_dS[ip][ke]; + dG1_dpc[ip][ke] = dG1_dS[ip][ke] * dfacePhaseVolFrac_dCapPres1[0][0][0][0]; + // GEOS_UNUSED_VAR( dG1_dpc[ip][ke] ); + } + else + { + dG2_dS[ip][ke] = dG_dS; + dhalfFlux2_dP[ip][ke] -= dG_dP; + dhalfFlux2_dS[ip][ke] -= dG2_dS[ip][ke]; + dG2_dpc[ip][ke] = dG2_dS[ip][ke] * dfacePhaseVolFrac_dCapPres2[0][0][0][0]; + // GEOS_UNUSED_VAR( dG2_dpc[ip][ke] ); + } + } + + // 3- Capillary: capillary pressure contribution + capillarity[ip][ix] = -1.0 * sign[ix] * sign[ip] * mobility[0] * mobility[1] / total_mobility * (capGrad[1] -capGrad[0]); + halfFluxVal[ip][ix] += capillarity[ip][ix]; + + for( integer ke = 0; ke < 2; ++ke ) + { + real64 dC_dP = sign[ix] * sign[ip] * (dMob_dP[0][ke] * mobility[1] * mobility[1] + dMob_dP[1][ke] * mobility[0] * mobility[0]) / (total_mobility * total_mobility) * + (capGrad[1] -capGrad[0]) + + sign[ix] * sign[ip] * mobility[0] * mobility[1] / total_mobility * (dCapGrad_dP[1][ke] - dCapGrad_dP[0][ke]); + + real64 dC_dS_term1 = sign[ix] * sign[ip] * (dMob_dS[0][ke] * mobility[1] * mobility[1] + dMob_dS[1][ke] * mobility[0] * mobility[0]) / (total_mobility * total_mobility) * + (capGrad[1] -capGrad[0]); + + real64 dC_dS_term2 = sign[ix] * sign[ip] * (mobility[0] * mobility[1]) / total_mobility; + + real64 dC_dS_term3 = (dCapGrad_dS[1][ke] - dCapGrad_dS[0][ke]); + + if( ix == 0 ) + { + dC1_dS[ip][ke] = dC_dS_term1 + dC_dS_term2 * dC_dS_term3; + dhalfFlux1_dP[ip][ke] -= dC_dP; + dhalfFlux1_dS[ip][ke] -= dC1_dS[ip][ke]; + // if (std::fabs(facePhaseVolFrac1[0][0] - 1.0) > 1e-8){ + dC1_dpc[ip][ke] = dC1_dS[ip][ke] * dfacePhaseVolFrac_dCapPres1[0][0][0][0]; + // } else { + // dC1_dpc[ip][ke] = dC_dS_term1 * dfacePhaseVolFrac_dCapPres1[0][0][0][0]; + // } + + // GEOS_UNUSED_VAR( dC1_dpc[ip][ke] ); + } + else + { + dC2_dS[ip][ke] = dC_dS_term1 + dC_dS_term2 * dC_dS_term3; + dhalfFlux2_dP[ip][ke] -= dC_dP; + dhalfFlux2_dS[ip][ke] -= dC2_dS[ip][ke]; + // if (std::fabs(facePhaseVolFrac2[0][0] - 1.0) > 1e-8){ + dC2_dpc[ip][ke] = dC2_dS[ip][ke] * dfacePhaseVolFrac_dCapPres2[0][0][0][0]; + // } else { + // dC2_dpc[ip][ke] = dC_dS_term1 * dfacePhaseVolFrac_dCapPres2[0][0][0][0]; + // } + // GEOS_UNUSED_VAR( dC2_dpc[ip][ke] ); + } + + } + + + if( halfFluxVal[ip][0] > 0.0 ) + { + k_up_0_check[ip] = true; + } + if( halfFluxVal[ip][1] > 0.0 ) + { + k_up_1_check[ip] = true; + } + + } // loop over phases + + } // loop over half fluxes + + check = true; + + // Brenier and Jaffre's PPU check: + bool flip0[2] = {0, 0}; + bool flip0_k_up[2] = {0, 0}; + bool flip1[2] = {0, 0}; + bool flip1_k_up[2] = {0, 0}; + // loop over phases + for( integer ip = 0; ip < 2; ++ip ) + { + bool k_up_0_b = !static_cast< bool >(k_up_0[ip]); + bool k_up_1_b = static_cast< bool >(k_up_1[ip]); + flip0_k_up[ip] = k_up_0_b; + flip1_k_up[ip] = k_up_1_b; + + if( std::fabs( uT ) < 1e-20 ) + { + + if((std::fabs( halfFluxVal[ip][0] ) < 1e-20) && (std::fabs( halfFluxVal[ip][1] ) < 1e-20)) + { + k_up_0_check[ip] = !k_up_0_b; + k_up_1_check[ip] = !k_up_1_b; + } + else + { + k_up_0_check[ip] = k_up_0_b; + k_up_1_check[ip] = k_up_1_b; + } + + if( k_up_0_check[ip] != k_up_0_b ) + { + flip0[ip] = 1; + check = false; + } + + if( k_up_1_check[ip] != k_up_1_b ) + { + flip1[ip] = 1; + check = false; + } + + } + else + { + if( std::fabs( halfFluxVal[ip][0] ) < 1e-20 ) + { + k_up_0_check[ip] = k_up_0_b; + } + + if( std::fabs( halfFluxVal[ip][1] ) < 1e-20 ) + { + k_up_1_check[ip] = k_up_1_b; + } + + if( k_up_0_check[ip] != k_up_0_b ) + { + k_up_0[ip] = static_cast< localIndex >(k_up_0_b); + check = false; + } + + if( k_up_1_check[ip] != k_up_1_b ) + { + k_up_1[ip] = static_cast< localIndex >(!k_up_1_b); + check = false; + } + } + + } + + if( flip0[0] || flip0[1] ) + { + k_up_0[0] = static_cast< localIndex >(flip0_k_up[0]); + k_up_0[1] = static_cast< localIndex >(flip0_k_up[1]); + } + + if( flip1[0] || flip1[1] ) + { + k_up_1[0] = static_cast< localIndex >(!flip1_k_up[0]); + k_up_1[1] = static_cast< localIndex >(!flip1_k_up[1]); + } + + } // while check for BJ PPU + + real64 constexpr eps2 = 1.0e-18; + // newton update + dhalfFlux_dpc[0][0] = dhalfFlux1_dS[0][1]*dfacePhaseVolFrac_dCapPres1[0][0][0][0]; + real64 dhalfFlux_dpc00 = dV1_dpc[0][1] - dG1_dpc[0][1] - dC1_dpc[0][1]; + dhalfFlux_dpc[0][1] = dhalfFlux2_dS[0][1]*dfacePhaseVolFrac_dCapPres2[0][0][0][0]; + real64 dhalfFlux_dpc01 = dV2_dpc[0][1] - dG2_dpc[0][1] - dC2_dpc[0][1]; + + dhalfFlux_dpc[1][0] = dhalfFlux1_dS[1][1]*dfacePhaseVolFrac_dCapPres1[0][0][0][0]; + real64 dhalfFlux_dpc10 = dV1_dpc[1][1] - dG1_dpc[1][1] - dC1_dpc[1][1]; + dhalfFlux_dpc[1][1] = dhalfFlux2_dS[1][1]*dfacePhaseVolFrac_dCapPres2[0][0][0][0]; + real64 dhalfFlux_dpc11 = dV2_dpc[1][1] - dG2_dpc[1][1] - dC2_dpc[1][1]; + + dhalfFlux_dpc[0][0] = dhalfFlux_dpc00; + dhalfFlux_dpc[0][1] = dhalfFlux_dpc01; + dhalfFlux_dpc[1][0] = dhalfFlux_dpc10; + dhalfFlux_dpc[1][1] = dhalfFlux_dpc11; + + local_jacobian = dhalfFlux_dpc[0][0] - dhalfFlux_dpc[0][1] + eps2; + local_residual = halfFluxVal[0][0] - halfFluxVal[0][1]; + + // if (iter == 1) { + // grad_phi[0] = local_residual; + // } + + // Check convergence + if( std::fabs( local_residual ) < tol ) + { + converged = 1; + break; // Converged + } + // converged = 0; + if( (!converged) && ( iter > (max_iter - 2)) ) + { + if( div == 0 ) + { + iter = 0; + div++; + Pc_int = Pc_min_all; + } + else if( div == 1 ) + { + iter = 0; + div++; + Pc_int = Pc_max_all; + } + else if( div > 1 ) + { + local_jacobian = 0.0; + std::cout << "**********************Diverged*******************" << std::endl; + iter = max_iter; + } + } + else + { + + real64 deltaPc = local_residual/local_jacobian; + + // if (std::fabs(facePhaseVolFrac1[0][0] - 1.0) < 1e-5 && (std::fabs(deltaPc * dfacePhaseVolFrac_dCapPres2[0][0][0][0]) < 0.05)){ + // ext_iter0++; + // } + // if (std::fabs(facePhaseVolFrac2[0][0] - 1.0) < 1e-5 && (std::fabs(deltaPc * dfacePhaseVolFrac_dCapPres1[0][0][0][0]) < 0.05)){ + // ext_iter1++; + // } + + // if (ext_iter0 > 20){ + // halfFluxVal[0][1] = halfFluxVal[0][0]; + // halfFluxVal[1][1] = halfFluxVal[1][0]; + // local_residual = halfFluxVal[0][0] - halfFluxVal[0][1]; + // } + + // if (ext_iter1 > 20){ + // halfFluxVal[0][0] = halfFluxVal[0][1]; + // halfFluxVal[1][0] = halfFluxVal[1][1]; + // local_residual = halfFluxVal[0][0] - halfFluxVal[0][1]; + // } + + if( std::fabs( local_residual ) < tol ) + { + converged = 1; + break; // Converged + } + + // Damping option: + if (damping) { + real64 max_dpc = fmax( fabs(dCapPres1_dfacePhaseVolFrac[0][0][0][0]), fabs(dCapPres2_dfacePhaseVolFrac[0][0][0][0])); + + real64 sign = std::copysign(1.0, deltaPc); + + deltaPc = fmin( fabs(deltaPc), max_dpc * 0.2 ); + deltaPc *= sign; + + } + + if (bisection && iter < 7){ + if ( iter == 0 ){ + + old_Pc_int = Pc_int; + Pc_int = next_Pc_int; + old_residual = local_residual; + + } else if (old_residual * local_residual < 0.0 ) { + + Pc_int = (next_Pc_int + old_Pc_int) / 2.0; + old_residual = local_residual; + old_Pc_int = next_Pc_int; + next_Pc_int = Pc_int; + + } else if (old_residual * local_residual > 0.0 ) { + + Pc_int = old_Pc_int; + old_residual = local_residual; + old_Pc_int = next_Pc_int; + next_Pc_int = Pc_int; + + } else { + + Pc_int = old_Pc_int; + old_residual = local_residual; + old_Pc_int = next_Pc_int; + next_Pc_int = Pc_int; + + } + + } else if (newton_path){ + Pc_int -= next_Pc_int; + + } else { + + Pc_int -= deltaPc; + + } + + + // truncate the updated capillary pressure (extended capillary pressure condition) for reporting/plotting: + + real64 faceCapPres1_plot = fmin( Pc1_max, fmax( Pc_int, Pc1_min )); + real64 faceCapPres2_plot = fmin( Pc2_max, fmax( Pc_int, Pc2_min )); + faceCapPres1_plot = fmin( Pc2_max, fmax( faceCapPres1_plot, Pc2_min )); + faceCapPres2_plot = fmin( Pc1_max, fmax( faceCapPres2_plot, Pc1_min )); + + // Write data to the file + outFile << GEOS_FMT( "{:10.10e}", local_jacobian ); + outFile << GEOS_FMT( ",{:10.10e}", local_residual ); + outFile << GEOS_FMT( ",{:10.10e}", halfFluxVal[0][0] ); + outFile << GEOS_FMT( ",{:10.10e}", halfFluxVal[0][1] ); + outFile << GEOS_FMT( ",{:10.10e}", Pc_int_iterate ); + outFile << GEOS_FMT( ",{:10.10e}", faceCapPres1[0][0][0] ); + outFile << GEOS_FMT( ",{:10.10e}", faceCapPres2[0][0][0] ); + outFile << GEOS_FMT( ",{:10.10e}", halfFluxVal[1][0] ); + outFile << GEOS_FMT( ",{:10.10e}", halfFluxVal[1][1] ); + outFile << GEOS_FMT( ",{:10.10e}", viscous[0][0] ); + outFile << GEOS_FMT( ",{:10.10e}", viscous[1][0] ); + outFile << GEOS_FMT( ",{:10.10e}", viscous[0][1] ); + outFile << GEOS_FMT( ",{:10.10e}", viscous[1][1] ); + outFile << GEOS_FMT( ",{:10.10e}", bouyancy[0][0] ); + outFile << GEOS_FMT( ",{:10.10e}", bouyancy[1][0] ); + outFile << GEOS_FMT( ",{:10.10e}", bouyancy[0][1] ); + outFile << GEOS_FMT( ",{:10.10e}", bouyancy[1][1] ); + outFile << GEOS_FMT( ",{:10.10e}", capillarity[0][0] ); + outFile << GEOS_FMT( ",{:10.10e}", capillarity[1][0] ); + outFile << GEOS_FMT( ",{:10.10e}", capillarity[0][1] ); + outFile << GEOS_FMT( ",{:10.10e}", capillarity[1][1] ); + outFile << GEOS_FMT( ",{:10.10e}", capPres1[0][0][0] ); + outFile << GEOS_FMT( ",{:10.10e}", capPres1[0][0][1] ); + outFile << GEOS_FMT( ",{:10.10e}", facePhaseVolFrac1[0][0] ); + outFile << GEOS_FMT( ",{:10.10e}", facePhaseVolFrac2[0][0] ); + outFile << std::endl; + + iter++; + + } + + + } // while loop + + if( converged ) + { + + // Global derivatives: + real64 constexpr eps3 = 1.0e-18; + + real64 const dPc_int_dS1 =(-1.0) * (dhalfFlux1_dS[0][0] + dhalfFlux_duT[0][0] * duT_dS[0] - dhalfFlux_duT[0][1] * duT_dS[0]) / (dhalfFlux_dpc[0][0] - dhalfFlux_dpc[0][1] + eps3); + real64 const dPc_int_dS2 =(-1.0) * (dhalfFlux_duT[0][0] * duT_dS[1] - dhalfFlux2_dS[0][0] - dhalfFlux_duT[0][1] * duT_dS[1]) / (dhalfFlux_dpc[0][0] - dhalfFlux_dpc[0][1] + eps3); + real64 const dPc_int_du =(-1.0) * (dhalfFlux_duT[0][0] - dhalfFlux_duT[0][1]) / (dhalfFlux_dpc[0][0] - dhalfFlux_dpc[0][1] + eps3); + + dFlux_dP[0][0] = (dhalfFlux_duT[0][0] * duT_dP[0] + dhalfFlux_dpc[0][0] * dPc_int_du * duT_dP[0]) * density2[0] + halfFluxVal[0][0] * dDens_dP2[0][0]; + dFlux_dS[0][0] = (dhalfFlux1_dS[0][0] + dhalfFlux_duT[0][0] * duT_dS[0] + dhalfFlux_dpc[0][0] * dPc_int_dS1) * density2[0]; + + dFlux_dP[0][1] = (dhalfFlux_duT[0][1] * duT_dP[1] + dhalfFlux_dpc[0][1] * dPc_int_du * duT_dP[1]) * density2[0] + halfFluxVal[0][1] * dDens_dP2[0][1]; + dFlux_dS[0][1] = (dhalfFlux2_dS[0][0] + dhalfFlux_duT[0][1] * duT_dS[1] + dhalfFlux_dpc[0][1] * dPc_int_dS2) * density2[0]; + + dFlux_dP[1][0] = (dhalfFlux_duT[1][0] * duT_dP[0] + dhalfFlux_dpc[1][0] * dPc_int_du * duT_dP[0]) * density2[1] + halfFluxVal[1][0] * dDens_dP2[1][0]; + dFlux_dS[1][0] = (dhalfFlux1_dS[1][0] + dhalfFlux_duT[1][0] * duT_dS[0] + dhalfFlux_dpc[1][0] * dPc_int_dS1) * density2[1]; + + dFlux_dP[1][1] = (dhalfFlux_duT[1][1] * duT_dP[1] + dhalfFlux_dpc[1][1] * dPc_int_du * duT_dP[1]) * density2[1] + halfFluxVal[1][1] * dDens_dP2[1][1]; + dFlux_dS[1][1] = (dhalfFlux2_dS[1][0] + dhalfFlux_duT[1][1] * duT_dS[1] + dhalfFlux_dpc[1][1] * dPc_int_dS2) * density2[1]; + + fluxVal[0] = halfFluxVal[0][0] * density2[0]; + fluxVal[1] = halfFluxVal[1][0] * density2[1]; + + } else { + std::cout << "**********************Diverged*******************" << std::endl; + + } + + phi[0] = fluxVal[0]; + phi[1] = fluxVal[1]; + + grad_phi_P[0] = dFlux_dP[0][0]; + grad_phi_P[1] = dFlux_dP[0][1]; + grad_phi_P[2] = dFlux_dP[1][0]; + grad_phi_P[3] = dFlux_dP[1][1]; + + grad_phi_S[0] = dFlux_dS[0][0]; + grad_phi_S[1] = dFlux_dS[0][1]; + grad_phi_S[2] = dFlux_dS[1][0]; + grad_phi_S[3] = dFlux_dS[1][1]; + + converged = 1; + GEOS_UNUSED_VAR( converged ); +// Close the file after writing + outFile.close(); + + } ); + + } ); + + } ); + + } ); + + +} /******************************** FluxComputeKernelBase ********************************/ @@ -68,7 +1320,6 @@ using namespace constitutive; * on template parameters (like stencil type and number of dofs). */ class FluxComputeKernelBase - { public: @@ -269,33 +1520,33 @@ class FluxComputeKernel : public FluxComputeKernelBase * @param[in] hasCapPressure flags for capillary pressure * @param[in] useTotalMassEquation flags for using total velocity formulation */ -FluxComputeKernel( integer const numPhases, - globalIndex const rankOffset, - STENCILWRAPPER const & stencilWrapper, - DofNumberAccessor const & dofNumberAccessor, - ImmiscibleMultiphaseFlowAccessors const & multiPhaseFlowAccessors, - MultiphaseFluidAccessors const & fluidAccessors, - CapPressureAccessors const & capPressureAccessors, - PermeabilityAccessors const & permeabilityAccessors, - real64 const & dt, - CRSMatrixView< real64, globalIndex const > const & localMatrix, - arrayView1d< real64 > const & localRhs, - integer const hasCapPressure, - integer const useTotalMassEquation, - integer const checkPhasePresenceInGravity ) - : FluxComputeKernelBase( numPhases, - rankOffset, - dofNumberAccessor, - multiPhaseFlowAccessors, - fluidAccessors, - capPressureAccessors, - permeabilityAccessors, - dt, - localMatrix, - localRhs, - hasCapPressure, - useTotalMassEquation, - checkPhasePresenceInGravity ), + FluxComputeKernel( integer const numPhases, + globalIndex const rankOffset, + STENCILWRAPPER const & stencilWrapper, + DofNumberAccessor const & dofNumberAccessor, + ImmiscibleMultiphaseFlowAccessors const & multiPhaseFlowAccessors, + MultiphaseFluidAccessors const & fluidAccessors, + CapPressureAccessors const & capPressureAccessors, + PermeabilityAccessors const & permeabilityAccessors, + real64 const & dt, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs, + integer const hasCapPressure, + integer const useTotalMassEquation, + integer const checkPhasePresenceInGravity ) + : FluxComputeKernelBase( numPhases, + rankOffset, + dofNumberAccessor, + multiPhaseFlowAccessors, + fluidAccessors, + capPressureAccessors, + permeabilityAccessors, + dt, + localMatrix, + localRhs, + hasCapPressure, + useTotalMassEquation, + checkPhasePresenceInGravity ), m_stencilWrapper( stencilWrapper ), m_seri( stencilWrapper.getElementRegionIndices() ), m_sesri( stencilWrapper.getElementSubRegionIndices() ), @@ -402,7 +1653,7 @@ FluxComputeKernel( integer const numPhases, * @param[inout] stack the stack variables * @param[in] NoOpFunc the function used to customize the computation of the flux */ - template< typename FUNC = NoOpFunc > // should change to multiphase + template< typename FUNC = NoOpFunc > // should change to multiphase GEOS_HOST_DEVICE void computeFlux( localIndex const iconn, StackVariables & stack, @@ -467,22 +1718,22 @@ FluxComputeKernel( integer const numPhases, continue; } - real64 const density = m_dens[seri[ke]][sesri[ke]][sei[ke]][0][ip]; // r = rho1 || rho2 - real64 const dDens_dP = m_dDens_dPres[seri[ke]][sesri[ke]][sei[ke]][0][ip][Deriv::dP]; // dr/dP = dr1/dP1 || dr2/dP + real64 const density = m_dens[seri[ke]][sesri[ke]][sei[ke]][0][ip]; // r = rho1 || rho2 + real64 const dDens_dP = m_dDens_dPres[seri[ke]][sesri[ke]][sei[ke]][0][ip][Deriv::dP]; // dr/dP = dr1/dP1 || dr2/dP // average density and derivatives - densMean[ip] += density; // rho = (rho1 + rho2) - dDensMean_dP[ip][ke] = dDens_dP; // drho/dP = { (dr1/dP1) , (dr2/dP2) } + densMean[ip] += density; // rho = (rho1 + rho2) + dDensMean_dP[ip][ke] = dDens_dP; // drho/dP = { (dr1/dP1) , (dr2/dP2) } denom++; } if( denom > 1 ) { - densMean[ip] /= denom; // rho = (rho1 + rho2) / denom + densMean[ip] /= denom; // rho = (rho1 + rho2) / denom for( integer ke = 0; ke < 2; ++ke ) { - dDensMean_dP[ip][ke] /= denom; // drho/dP = { (dr1/dP1) / denom , (dr2/dP2) / denom } + dDensMean_dP[ip][ke] /= denom; // drho/dP = { (dr1/dP1) / denom , (dr2/dP2) / denom } } } @@ -501,106 +1752,114 @@ FluxComputeKernel( integer const numPhases, localIndex const esr = sesri[ke]; localIndex const ei = sei[ke]; - real64 const pressure = m_pres[er][esr][ei]; // P = P1 || P2 - presGrad[ip] += trans[ke] * pressure; // DPv = T (P1 - P2) - dPresGrad_dTrans += signPotDiff[ke] * pressure; // dDPv/dT = (P1 - P2) - dPresGrad_dP[ip][ke] = trans[ke]; // dDPv/dP = { T , -T } + real64 const pressure = m_pres[er][esr][ei]; // P = P1 || P2 + presGrad[ip] += trans[ke] * pressure; // DPv = T (P1 - P2) + dPresGrad_dTrans += signPotDiff[ke] * pressure; // dDPv/dT = (P1 - P2) + dPresGrad_dP[ip][ke] = trans[ke]; // dDPv/dP = { T , -T } - real64 const gravD = trans[ke] * m_gravCoef[er][esr][ei]; // D = T g z1 || -T g z2 - real64 pot = trans[ke] * pressure - densMean[ip] * gravD; // Phi = T P1 - rho T g z1 || -T P2 + rho T g z2 + real64 const gravD = trans[ke] * m_gravCoef[er][esr][ei]; // D = T g z1 || -T g z2 + real64 pot = trans[ke] * pressure - densMean[ip] * gravD; // Phi = T P1 - rho T g z1 || -T P2 + rho T g z2 - gravHead[ip] += densMean[ip] * gravD; // DPg = rho (T g z1 - T g z2) = T rho g (z1 - z2) - dGravHead_dTrans += signPotDiff[ke] * densMean[ip] * m_gravCoef[er][esr][ei]; // dDPg/dT = rho g z1 - rho g z2 = rho g (z1 - z2) + gravHead[ip] += densMean[ip] * gravD; // DPg = rho (T g z1 - T g z2) = T rho g (z1 - + // z2) + dGravHead_dTrans += signPotDiff[ke] * densMean[ip] * m_gravCoef[er][esr][ei]; // dDPg/dT = rho g z1 - rho g z2 = rho g (z1 - + // z2) for( integer i = 0; i < 2; ++i ) { - dGravHead_dP[ip][i] += dDensMean_dP[ip][i] * gravD; // dDPg/dP = {drho/dP1 * T g (z1 - z2) , drho/dP2 * T g (z1 - z2)} + dGravHead_dP[ip][i] += dDensMean_dP[ip][i] * gravD; // dDPg/dP = {drho/dP1 * T g (z1 - z2) , drho/dP2 * T g (z1 - z2)} } - if( m_hasCapPressure ) // check sign convention + if( m_hasCapPressure ) // check sign convention { - real64 const capPres = m_phaseCapPressure[er][esr][ei][0][ip]; // Pc = Pc1 || Pc2 - dCapGrad_dTrans -= signPotDiff[ke] * capPres; // dDPc/dT = (-Pc1 + Pc2) - pot -= trans[ke] * capPres; // Phi = T P1 - rho T g z1 - T Pc1 || -T P2 + rho T g z2 + T - // Pc2 - capGrad[ip] -= trans[ke] * capPres; // DPc = T (-Pc1 + Pc2) + real64 const capPres = m_phaseCapPressure[er][esr][ei][0][ip]; // Pc = Pc1 || Pc2 + dCapGrad_dTrans -= signPotDiff[ke] * capPres; // dDPc/dT = (-Pc1 + Pc2) + pot -= trans[ke] * capPres; // Phi = T P1 - rho T g z1 - T Pc1 || -T P2 + rho T g z2 + T + // Pc2 + capGrad[ip] -= trans[ke] * capPres; // DPc = T (-Pc1 + Pc2) } - potScale = fmax( potScale, fabs( pot ) ); // maxPhi = Phi1 > Phi2 ? Phi1 : Phi2 + potScale = fmax( potScale, fabs( pot ) ); // maxPhi = Phi1 > Phi2 ? Phi1 : Phi2 } for( integer ke = 0; ke < 2; ++ke ) { - dPresGrad_dP[ip][ke] += dTrans_dP[ke] * dPresGrad_dTrans; // dDPv/dP = { T + dT/dP1 * (P1 - P2) , -T + dT/dP2 * (P1 - P2)} - dGravHead_dP[ip][ke] += dTrans_dP[ke] * dGravHead_dTrans; // dDPg/dP = { drho/dP1 * T g (z1 - z2) + dT/dP1 * rho g (z1 - z2) , - // drho/dP2 * T g (z1 - z2) + dT/dP2 * rho g (z1 - z2) } + dPresGrad_dP[ip][ke] += dTrans_dP[ke] * dPresGrad_dTrans; // dDPv/dP = { T + dT/dP1 * (P1 - P2) , -T + dT/dP2 * (P1 - P2)} + dGravHead_dP[ip][ke] += dTrans_dP[ke] * dGravHead_dTrans; // dDPg/dP = { drho/dP1 * T g (z1 - z2) + dT/dP1 * rho g (z1 - z2) + // , + // drho/dP2 * T g (z1 - z2) + dT/dP2 * rho g (z1 - z2) + // } if( m_hasCapPressure ) { - real64 const dCapPres_dS = m_dPhaseCapPressure_dPhaseVolFrac[seri[ke]][sesri[ke]][sei[ke]][0][ip][ip]; // dPc/dS = dPc1/dS1 || - // dPc2/dS2 - dCapGrad_dP[ip][ke] += dTrans_dP[ke] * dCapGrad_dTrans; // dDPc/dP = { dT/dP1 * - // (-Pc1 + Pc2) , - // dT/dP2 * - // (-Pc1 + Pc2) } - dCapGrad_dS[ip][ke] -= trans[ke] * dCapPres_dS; // dDPc/dS = { -T * - // dPc1/dS1 , T * - // dPc2/dS2 } + real64 const dCapPres_dS = m_dPhaseCapPressure_dPhaseVolFrac[seri[ke]][sesri[ke]][sei[ke]][0][ip][ip]; // dPc/dS = dPc1/dS1 + // || + // dPc2/dS2 + dCapGrad_dP[ip][ke] += dTrans_dP[ke] * dCapGrad_dTrans; // dDPc/dP = { dT/dP1 + // * + // (-Pc1 + Pc2) , + // dT/dP2 + // * + // (-Pc1 + Pc2) } + dCapGrad_dS[ip][ke] -= trans[ke] * dCapPres_dS; // dDPc/dS = { -T * + // dPc1/dS1 , T * + // dPc2/dS2 } } } // *** upwinding *** // compute potential gradient - real64 potGrad = presGrad[ip] - gravHead[ip]; // DPhi = T (P1 - P2) - T rho g (z1 - z2) + real64 potGrad = presGrad[ip] - gravHead[ip]; // DPhi = T (P1 - P2) - T rho g (z1 - z2) if( m_hasCapPressure ) { - potGrad += capGrad[ip]; // DPhi = T (P1 - P2) - T rho g (z1 - z2) + T (-Pc1 + Pc2) + potGrad += capGrad[ip]; // DPhi = T (P1 - P2) - T rho g (z1 - z2) + T (-Pc1 + Pc2) } // compute upwinding tolerance real64 constexpr upwRelTol = 1e-8; - real64 const upwAbsTol = fmax( potScale * upwRelTol, LvArray::NumericLimits< real64 >::epsilon ); // abstol = maxPhi * tol > eps ? - // maxPhi * tol : eps + real64 const upwAbsTol = fmax( potScale * upwRelTol, LvArray::NumericLimits< real64 >::epsilon ); // abstol = maxPhi * tol > eps + // ? + // maxPhi * tol : eps // decide mobility coefficients - smooth variation in [-upwAbsTol; upwAbsTol] - real64 const alpha = ( potGrad + upwAbsTol ) / ( 2 * upwAbsTol ); // alpha = (DPhi + abstol) / abstol / 2 + real64 const alpha = ( potGrad + upwAbsTol ) / ( 2 * upwAbsTol ); // alpha = (DPhi + abstol) / abstol / 2 // choose upstream cell - if( alpha <= 0.0 || alpha >= 1.0 ) // no smoothing needed + if( alpha <= 0.0 || alpha >= 1.0 ) // no smoothing needed { - localIndex const k_up = 1 - localIndex( fmax( fmin( alpha, 1.0 ), 0.0 ) ); // 1 upwind -> k_up = 0 || 2 upwind -> k_up = 1 + localIndex const k_up = 1 - localIndex( fmax( fmin( alpha, 1.0 ), 0.0 ) ); // 1 upwind -> k_up = 0 || 2 upwind -> k_up = 1 - mobility[ip] = m_mob[seri[k_up]][sesri[k_up]][sei[k_up]][ip]; // M = Mupstream - dMob_dP[ip][k_up] = m_dMob[seri[k_up]][sesri[k_up]][sei[k_up]][ip][Deriv::dP]; // dM/dP = {dM/dP1 , 0} OR {0 , dM/dP2} - dMob_dS[ip][k_up] = m_dMob[seri[k_up]][sesri[k_up]][sei[k_up]][ip][Deriv::dS]; // dM/dS = {dM/dS1 , 0} OR {0 , dM/dS2} + mobility[ip] = m_mob[seri[k_up]][sesri[k_up]][sei[k_up]][ip]; // M = Mupstream + dMob_dP[ip][k_up] = m_dMob[seri[k_up]][sesri[k_up]][sei[k_up]][ip][Deriv::dP]; // dM/dP = {dM/dP1 , 0} OR {0 , dM/dP2} + dMob_dS[ip][k_up] = m_dMob[seri[k_up]][sesri[k_up]][sei[k_up]][ip][Deriv::dS]; // dM/dS = {dM/dS1 , 0} OR {0 , dM/dS2} } - else // perform smoothing + else // perform smoothing { real64 const mobWeights[2] = { alpha, 1.0 - alpha }; for( integer ke = 0; ke < 2; ++ke ) { - mobility[ip] += mobWeights[ke] * m_mob[seri[ke]][sesri[ke]][sei[ke]][ip]; // M = alpha * M1 + (1 - alpha) * M2 - dMob_dP[ip][ke] = mobWeights[ke] * m_dMob[seri[ke]][sesri[ke]][sei[ke]][ip][Deriv::dP]; // dM/dP = {alpha * dM1/dP1 , (1 - - // alpha) * dM2/dP2} - dMob_dS[ip][ke] = mobWeights[ke] * m_dMob[seri[ke]][sesri[ke]][sei[ke]][ip][Deriv::dS]; // dM/dP = {alpha * dM1/dS1 , (1 - - // alpha) * dM2/dS2} + mobility[ip] += mobWeights[ke] * m_mob[seri[ke]][sesri[ke]][sei[ke]][ip]; // M = alpha * M1 + (1 - alpha) * M2 + dMob_dP[ip][ke] = mobWeights[ke] * m_dMob[seri[ke]][sesri[ke]][sei[ke]][ip][Deriv::dP]; // dM/dP = {alpha * dM1/dP1 , (1 - + // alpha) * dM2/dP2} + dMob_dS[ip][ke] = mobWeights[ke] * m_dMob[seri[ke]][sesri[ke]][sei[ke]][ip][Deriv::dS]; // dM/dP = {alpha * dM1/dS1 , (1 - + // alpha) * dM2/dS2} } } // pressure gradient depends on all points in the stencil for( integer ke = 0; ke < 2; ++ke ) { - dFlux_dP[ip][ke] += dPresGrad_dP[ip][ke]; // dF/dP = { T + dT/dP1 * (P1 - P2) , - // -T + dT/dP2 * (P1 - P2) } + dFlux_dP[ip][ke] += dPresGrad_dP[ip][ke]; // dF/dP = { T + dT/dP1 * (P1 - P2) , + // -T + dT/dP2 * (P1 - P2) } } // gravitational head depends only on the two cells connected (same as mean density) for( integer ke = 0; ke < 2; ++ke ) { - dFlux_dP[ip][ke] -= dGravHead_dP[ip][ke]; // dF/dP = { T + dT/dP1 * (P1 - P2) - drho/dP1 * T g (z1 - z2) - dT/dP1 * rho g (z1 - - // z2) , - // -T + dT/dP2 * (P1 - P2) - drho/dP2 * T g (z1 - z2) - dT/dP2 * rho g (z1 - - // z2) } + dFlux_dP[ip][ke] -= dGravHead_dP[ip][ke]; // dF/dP = { T + dT/dP1 * (P1 - P2) - drho/dP1 * T g (z1 - z2) - dT/dP1 * rho g (z1 - + // z2) , + // -T + dT/dP2 * (P1 - P2) - drho/dP2 * T g (z1 - z2) - dT/dP2 * rho g (z1 - + // z2) } } // capillary pressure contribution @@ -608,38 +1867,38 @@ FluxComputeKernel( integer const numPhases, { for( integer ke = 0; ke < 2; ++ke ) { - dFlux_dP[ip][ke] += dCapGrad_dP[ip][ke]; // dF/dP = { T + dT/dP1 * (P1 - P2) - drho/dP1 * T g (z1 - z2) - dT/dP1 * rho g (z1 - // - z2) + dT/dP1 * (-Pc1 + Pc2) , - // -T + dT/dP2 * (P1 - P2) - drho/dP2 * T g (z1 - z2) - dT/dP2 * rho g (z1 - // - z2) + dT/dP2 * (-Pc1 + Pc2) } + dFlux_dP[ip][ke] += dCapGrad_dP[ip][ke]; // dF/dP = { T + dT/dP1 * (P1 - P2) - drho/dP1 * T g (z1 - z2) - dT/dP1 * rho g (z1 + // - z2) + dT/dP1 * (-Pc1 + Pc2) , + // -T + dT/dP2 * (P1 - P2) - drho/dP2 * T g (z1 - z2) - dT/dP2 * rho g (z1 + // - z2) + dT/dP2 * (-Pc1 + Pc2) } - dFlux_dS[ip][ke] += dCapGrad_dS[ip][ke]; // dF/dS = { T * -dPc/dS1 , T * dPc/dS2 } + dFlux_dS[ip][ke] += dCapGrad_dS[ip][ke]; // dF/dS = { T * -dPc/dS1 , T * dPc/dS2 } } } // compute the flux and derivatives using upstream cell mobility - fluxVal[ip] = mobility[ip] * potGrad; // F = M * DPhi + fluxVal[ip] = mobility[ip] * potGrad; // F = M * DPhi for( integer ke = 0; ke < 2; ++ke ) { - dFlux_dP[ip][ke] *= mobility[ip]; // dF/dP = { M [ T + dT/dP1 * (P1 - P2) - drho/dP1 * T g (z1 - z2) - dT/dP1 * rho g (z1 - - // z2) + dT/dP1 * (-Pc1 + Pc2)] , - // M [-T + dT/dP2 * (P1 - P2) - drho/dP2 * T g (z1 - z2) - dT/dP2 * rho g (z1 - - // z2) + dT/dP2 * (-Pc1 + Pc2)] } + dFlux_dP[ip][ke] *= mobility[ip]; // dF/dP = { M [ T + dT/dP1 * (P1 - P2) - drho/dP1 * T g (z1 - z2) - dT/dP1 * rho g (z1 - + // z2) + dT/dP1 * (-Pc1 + Pc2)] , + // M [-T + dT/dP2 * (P1 - P2) - drho/dP2 * T g (z1 - z2) - dT/dP2 * rho g (z1 - + // z2) + dT/dP2 * (-Pc1 + Pc2)] } - dFlux_dS[ip][ke] *= mobility[ip]; // dF/dS = { M [T * -dPc/dS1] , M [T * dPc/dS2] } + dFlux_dS[ip][ke] *= mobility[ip]; // dF/dS = { M [T * -dPc/dS1] , M [T * dPc/dS2] } } // add contribution from upstream cell mobility derivatives for( integer ke = 0; ke < 2; ++ke ) { - dFlux_dP[ip][ke] += dMob_dP[ip][ke] * potGrad; // dF/dP = { M [ T + dT/dP1 * (P1 - P2) - drho1/dP * T g (z1 - z2) - dT/dP1 * - // rho g (z1 - z2) + dT/dP1 * (-Pc1 + Pc2)] + dM/dP1 * DPhi , - // M [-T + dT/dP2 * (P1 - P2) - drho2/dP * T g (z1 - z2) - dT/dP2 * - // rho g (z1 - z2) + dT/dP2 * (-Pc1 + Pc2)] + dM/dP2 * DPhi } + dFlux_dP[ip][ke] += dMob_dP[ip][ke] * potGrad; // dF/dP = { M [ T + dT/dP1 * (P1 - P2) - drho1/dP * T g (z1 - z2) - dT/dP1 * + // rho g (z1 - z2) + dT/dP1 * (-Pc1 + Pc2)] + dM/dP1 * DPhi , + // M [-T + dT/dP2 * (P1 - P2) - drho2/dP * T g (z1 - z2) - dT/dP2 * + // rho g (z1 - z2) + dT/dP2 * (-Pc1 + Pc2)] + dM/dP2 * DPhi } - dFlux_dS[ip][ke] += dMob_dS[ip][ke] * potGrad; // dF/dS = { M [T * -dPc/dS1] + dM/dS1 * DPhi , M [T * dPc/dS2] + dM/dS2 * DPhi - // } + dFlux_dS[ip][ke] += dMob_dS[ip][ke] * potGrad; // dF/dS = { M [T * -dPc/dS1] + dM/dS1 * DPhi , M [T * dPc/dS2] + dM/dS2 * DPhi + // } } // populate local flux vector and derivatives @@ -660,14 +1919,14 @@ FluxComputeKernel( integer const numPhases, } // Customize the kernel with this lambda - kernelOp( k, seri, sesri, sei, connectionIndex, alpha, mobility, potGrad, fluxVal, dFlux_dP, dFlux_dS ); // Not sure what this - // does + kernelOp( k, seri, sesri, sei, connectionIndex, alpha, mobility, potGrad, fluxVal, dFlux_dP, dFlux_dS ); // Not sure what this + // does - } // loop over phases + } // loop over phases connectionIndex++; } - } // loop over connection elements + } // loop over connection elements } /** @@ -675,7 +1934,7 @@ FluxComputeKernel( integer const numPhases, * @param[in] iconn the connection index * @param[inout] stack the stack variables */ - template< typename FUNC = NoOpFunc > // should change to multiphase + template< typename FUNC = NoOpFunc > // should change to multiphase GEOS_HOST_DEVICE void complete( localIndex const iconn, StackVariables & stack, @@ -770,7 +2029,7 @@ FluxComputeKernel( integer const numPhases, * @tparam RELPERMWRAPPER the type of the realtive permeability wrapper * @brief Define the interface for the assembly kernel in charge of flux terms */ -template< integer NUM_EQN, integer NUM_DOF, typename STENCILWRAPPER, typename CAPPRESWRAPPER, typename RELPERMWRAPPER > +template< integer NUM_EQN, integer NUM_DOF, typename STENCILWRAPPER, typename CAPPRESWRAPPER, typename RELPERMWRAPPER > class FluxComputeInterfaceConditionKernel : public FluxComputeKernel< NUM_EQN, NUM_DOF, STENCILWRAPPER > { public: @@ -835,22 +2094,30 @@ class FluxComputeInterfaceConditionKernel : public FluxComputeKernel< NUM_EQN, N * @param[in] useTotalMassEquation flags for using total velocity formulation */ FluxComputeInterfaceConditionKernel( integer const numPhases, - globalIndex const rankOffset, - STENCILWRAPPER const & stencilWrapper, - CAPPRESWRAPPER const & capPressureWrapper, - RELPERMWRAPPER const & relPermWrapper, - DofNumberAccessor const & dofNumberAccessor, - ImmiscibleMultiphaseFlowAccessors const & multiPhaseFlowAccessors, - MultiphaseFluidAccessors const & fluidAccessors, - CapPressureAccessors const & capPressureAccessors, - PermeabilityAccessors const & permeabilityAccessors, - real64 const & dt, - CRSMatrixView< real64, globalIndex const > const & localMatrix, - arrayView1d< real64 > const & localRhs, - integer const hasCapPressure, - integer const useTotalMassEquation, - integer const checkPhasePresenceInGravity, - localIndex const GEOS_UNUSED_PARAM(domainSize) ) + globalIndex const rankOffset, + STENCILWRAPPER const & stencilWrapper, + CAPPRESWRAPPER const & capPressureWrapper, + RELPERMWRAPPER const & relPermWrapper, + DofNumberAccessor const & dofNumberAccessor, + ImmiscibleMultiphaseFlowAccessors const & multiPhaseFlowAccessors, + MultiphaseFluidAccessors const & fluidAccessors, + CapPressureAccessors const & capPressureAccessors, + PermeabilityAccessors const & permeabilityAccessors, + real64 const & dt, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs, + integer const hasCapPressure, + integer const useTotalMassEquation, + integer const checkPhasePresenceInGravity, + string_array const & interfaceFaceSetNames, + stdVector< std::array< std::tuple< constitutive::RelativePermeabilityBase *, + constitutive::CapillaryPressureBase *, + constitutive::TwoPhaseImmiscibleFluid * >, 2 > > const & interfaceConstitutivePairs, + unordered_map< localIndex, localIndex > const & interfaceRegionByConnector, + std::tuple< constitutive::RelativePermeabilityBase *, + constitutive::CapillaryPressureBase *, + constitutive::TwoPhaseImmiscibleFluid * > const & interfaceConstitutivePairs_temp, + localIndex const GEOS_UNUSED_PARAM( domainSize ) ) : Base( numPhases, rankOffset, stencilWrapper, @@ -866,7 +2133,11 @@ class FluxComputeInterfaceConditionKernel : public FluxComputeKernel< NUM_EQN, N useTotalMassEquation, checkPhasePresenceInGravity ), m_capPressureWrapper( capPressureWrapper ), - m_relPermWrapper( relPermWrapper ) + m_relPermWrapper( relPermWrapper ), + m_interfaceFaceSetNames( interfaceFaceSetNames ), + m_interfaceConstitutivePairs( interfaceConstitutivePairs ), + m_interfaceRegionByConnector( interfaceRegionByConnector ), + m_interfaceConstitutivePairs_temp( interfaceConstitutivePairs_temp ) {} /** @@ -876,15 +2147,30 @@ class FluxComputeInterfaceConditionKernel : public FluxComputeKernel< NUM_EQN, N * @param[inout] stack the stack variables * @param[in] NoOpFunc the function used to customize the computation of the flux */ - - template< typename FUNC = NoOpFunc > // should change to multiphase + + template< typename FUNC = NoOpFunc > // should change to multiphase GEOS_HOST_DEVICE void computeFlux( localIndex const iconn, StackVariables & stack, FUNC && kernelOp = NoOpFunc{} ) const { - // first, compute the transmissibilities at this face // get k and dk/dP from global arrays - // and place in stack + + bool connectorHasInterfaceConditionQ = false; + bool anyInterfaceConditionsQ = not m_interfaceConstitutivePairs.empty(); + if (anyInterfaceConditionsQ) { + connectorHasInterfaceConditionQ = + m_interfaceRegionByConnector.find(iconn) != m_interfaceRegionByConnector.end(); + } + + + // if (connectorHasInterfaceConditionQ){ + // // Improved transmission conditions + // int ammar_code = 0; + // }else{ + // // Regular contribution + // int standard_code = 0; + // } + m_stencilWrapper.computeWeights( iconn, m_permeability, m_dPerm_dPres, @@ -894,30 +2180,14 @@ class FluxComputeInterfaceConditionKernel : public FluxComputeKernel< NUM_EQN, N localIndex k[2]; localIndex connectionIndex = 0; - // // Create an output file stream object (ofstream) - // std::ofstream outFile("iterations.csv"); - - - // // Write data to the file - // outFile << "Jacobian"; - // outFile << ","; - // outFile << "residual"; - // outFile << ","; - // outFile << "F_alpha"; - // outFile << ","; - // outFile << "F_beta"; - // outFile << ","; - // outFile << "Pc"; - // outFile << ","; - // outFile << "newton"; - // outFile << std::endl; - - + // one-sided transmissibility m_stencilWrapper.computeHalfWeights( iconn, - m_permeability, - m_dPerm_dPres, - stack.transmissibilityHat, - stack.dTransHat_dPres ); + m_permeability, + m_dPerm_dPres, + stack.transmissibilityHat, + stack.dTransHat_dPres ); + + for( k[0] = 0; k[0] < stack.numFluxElems; ++k[0] ) { @@ -949,6 +2219,9 @@ class FluxComputeInterfaceConditionKernel : public FluxComputeKernel< NUM_EQN, N real64 density2[numEqn]{}; real64 dDens_dP2[numEqn][2]{}; + real64 viscosity[numEqn]{}; + real64 dVisc_dP[numEqn][2]{}; + real64 gravCoef2[numEqn]{}; real64 gravCoefHat[numEqn]{}; real64 uT = 0; @@ -962,14 +2235,18 @@ class FluxComputeInterfaceConditionKernel : public FluxComputeKernel< NUM_EQN, N real64 const trans[2] = { stack.transmissibility[connectionIndex][0], stack.transmissibility[connectionIndex][1] }; real64 const dTrans_dP[2] = { stack.dTrans_dPres[connectionIndex][0], stack.dTrans_dPres[connectionIndex][1] }; - real64 const transHat[2] = { stack.transmissibilityHat[connectionIndex][0], stack.transmissibilityHat[connectionIndex][1] }; - real64 const dTransHat_dP[2] = { stack.dTransHat_dPres[connectionIndex][0], stack.dTransHat_dPres[connectionIndex][1] }; + real64 const transHat[2] = { stack.transmissibilityHat[connectionIndex][0], stack.transmissibilityHat[connectionIndex][1] * -1.0}; + real64 const dTransHat_dP[2] = { stack.dTransHat_dPres[connectionIndex][0], stack.dTransHat_dPres[connectionIndex][1] * -1.0}; // cell indices localIndex const seri[2] = {m_seri( iconn, k[0] ), m_seri( iconn, k[1] )}; localIndex const sesri[2] = {m_sesri( iconn, k[0] ), m_sesri( iconn, k[1] )}; localIndex const sei[2] = {m_sei( iconn, k[0] ), m_sei( iconn, k[1] )}; + stdVector< real64 > saturations = {m_phaseVolFrac[seri[0]][sesri[0]][sei[0]][0], m_phaseVolFrac[seri[1]][sesri[1]][sei[1]][0] }; + stdVector< real64 > pressures = {m_pres[seri[0]][sesri[0]][sei[0]], m_pres[seri[1]][sesri[1]][sei[1]] }; + bool isJfunction = 1; + // loop over phases for( integer ip = 0; ip < m_numPhases; ++ip ) { @@ -984,13 +2261,11 @@ class FluxComputeInterfaceConditionKernel : public FluxComputeKernel< NUM_EQN, N continue; } - real64 const density = m_dens[seri[ke]][sesri[ke]][sei[ke]][0][ip]; // r = rho1 || rho2 - real64 const dDens_dP = m_dDens_dPres[seri[ke]][sesri[ke]][sei[ke]][0][ip][Deriv::dP]; // dr/dP = dr1/dP1 || dr2/dP - + real64 const density = m_dens[seri[ke]][sesri[ke]][sei[ke]][0][ip]; // r = rho1 || rho2 + real64 const dDens_dP = m_dDens_dPres[seri[ke]][sesri[ke]][sei[ke]][0][ip][Deriv::dP]; // dr/dP = dr1/dP1 || dr2/dP // average density and derivatives - densMean[ip] += density; // rho = (rho1 + rho2) - dDensMean_dP[ip][ke] = dDens_dP; // drho/dP = { (dr1/dP1) , (dr2/dP2) } - + densMean[ip] += density; // rho = (rho1 + rho2) + dDensMean_dP[ip][ke] = dDens_dP; // drho/dP = { (dr1/dP1) , (dr2/dP2) } denom++; } @@ -1020,17 +2295,19 @@ class FluxComputeInterfaceConditionKernel : public FluxComputeKernel< NUM_EQN, N localIndex const esr = sesri[ke]; localIndex const ei = sei[ke]; - real64 const pressure = m_pres[er][esr][ei]; // P = P1 || P2 - presGrad[ip] += trans[ke] * pressure; // DPv = T (P1 - P2) - dPresGrad_dTrans += signPotDiff[ke] * pressure; // dDPv/dT = (P1 - P2) - dPresGrad_dP[ip][ke] = trans[ke]; // dDPv/dP = { T , -T } + real64 const pressure = m_pres[er][esr][ei]; // P = P1 || P2 + presGrad[ip] += trans[ke] * pressure; // DPv = T (P1 - P2) + dPresGrad_dTrans += signPotDiff[ke] * pressure; // dDPv/dT = (P1 - P2) + dPresGrad_dP[ip][ke] = trans[ke]; // dDPv/dP = { T , -T } - real64 const gravD = trans[ke] * m_gravCoef[er][esr][ei]; // D = T g z1 || -T g z2 + real64 const gravD = trans[ke] * m_gravCoef[er][esr][ei]; // D = T g z1 || -T g z2 real64 pot = trans[ke] * pressure - densMean[ip] * gravD; // Phi = T P1 - rho T g z1 || -T P2 + rho T g z2 gravCoefHat[0] += m_gravCoef[er][esr][ei] * 0.5; gravCoefHat[1] += m_gravCoef[er][esr][ei] * 0.5; - gravHead[ip] += densMean[ip] * gravD; // DPg = rho (T g z1 - T g z2) = T rho g (z1 - z2) + gravCoef2[ke] = m_gravCoef[er][esr][ei]; + + gravHead[ip] += densMean[ip] * gravD; // DPg = rho (T g z1 - T g z2) = T rho g (z1 - z2) dGravHead_dTrans += signPotDiff[ke] * densMean[ip] * m_gravCoef[er][esr][ei]; // dDPg/dT = rho g z1 - rho g z2 = rho g (z1 - z2) for( integer i = 0; i < 2; ++i ) @@ -1038,16 +2315,16 @@ class FluxComputeInterfaceConditionKernel : public FluxComputeKernel< NUM_EQN, N dGravHead_dP[ip][i] += dDensMean_dP[ip][i] * gravD; // dDPg/dP = {drho/dP1 * T g (z1 - z2) , drho/dP2 * T g (z1 - z2)} } - if( m_hasCapPressure ) // check sign convention + if( m_hasCapPressure ) // check sign convention { - real64 const capPres = m_phaseCapPressure[er][esr][ei][0][ip]; // Pc = Pc1 || Pc2 - jFMultiplier[ip][ke] = m_jFuncMultiplier[er][esr][ei][0]; + real64 const capPres = m_phaseCapPressure[er][esr][ei][0][ip]; // Pc = Pc1 || Pc2 + jFMultiplier[ip][ke] = m_jFuncMultiplier[er][esr][ei][0]; capPresIC[ip][ke] = capPres; - dCapGrad_dTrans -= signPotDiff[ke] * capPres; // dDPc/dT = (-Pc1 + Pc2) - pot -= trans[ke] * capPres; // Phi = T P1 - rho T g z1 - T Pc1 || -T P2 + rho T g z2 + T - // Pc2 - capGrad[ip] -= trans[ke] * capPres; // DPc = T (-Pc1 + Pc2) + dCapGrad_dTrans -= signPotDiff[ke] * capPres; // dDPc/dT = (-Pc1 + Pc2) + pot -= trans[ke] * capPres; // Phi = T P1 - rho T g z1 - T Pc1 || -T P2 + rho T g z2 + T + // Pc2 + capGrad[ip] -= trans[ke] * capPres; // DPc = T (-Pc1 + Pc2) } potScale = fmax( potScale, fabs( pot ) ); // maxPhi = Phi1 > Phi2 ? Phi1 : Phi2 @@ -1056,25 +2333,24 @@ class FluxComputeInterfaceConditionKernel : public FluxComputeKernel< NUM_EQN, N for( integer ke = 0; ke < 2; ++ke ) { - dPresGrad_dP[ip][ke] += dTrans_dP[ke] * dPresGrad_dTrans; // dDPv/dP = { T + dT/dP1 * (P1 - P2) , -T + dT/dP2 * (P1 - P2)} - dGravHead_dP[ip][ke] += dTrans_dP[ke] * dGravHead_dTrans; // dDPg/dP = { drho/dP1 * T g (z1 - z2) + dT/dP1 * rho g (z1 - z2) , - // drho/dP2 * T g (z1 - z2) + dT/dP2 * rho g (z1 - z2) } + dPresGrad_dP[ip][ke] += dTrans_dP[ke] * dPresGrad_dTrans; // dDPv/dP = { T + dT/dP1 * (P1 - P2) , -T + dT/dP2 * (P1 - P2)} + dGravHead_dP[ip][ke] += dTrans_dP[ke] * dGravHead_dTrans; // dDPg/dP = { drho/dP1 * T g (z1 - z2) + dT/dP1 * rho g (z1 - z2) , + // drho/dP2 * T g (z1 - z2) + dT/dP2 * rho g (z1 - z2) } if( m_hasCapPressure ) { real64 const dCapPres_dS = m_dPhaseCapPressure_dPhaseVolFrac[seri[ke]][sesri[ke]][sei[ke]][0][ip][ip]; // dPc/dS = dPc1/dS1 || - // dPc2/dS2 - dCapGrad_dP[ip][ke] += dTrans_dP[ke] * dCapGrad_dTrans; // dDPc/dP = { dT/dP1 * - // (-Pc1 + Pc2) , - // dT/dP2 * - // (-Pc1 + Pc2) } - dCapGrad_dS[ip][ke] -= trans[ke] * dCapPres_dS; // dDPc/dS = { -T * - // dPc1/dS1 , T * - // dPc2/dS2 } + // dPc2/dS2 + dCapGrad_dP[ip][ke] += dTrans_dP[ke] * dCapGrad_dTrans; // dDPc/dP = { dT/dP1 * + // (-Pc1 + Pc2) , + // dT/dP2 * + // (-Pc1 + Pc2) } + dCapGrad_dS[ip][ke] -= trans[ke] * dCapPres_dS; // dDPc/dS = { -T * + // dPc1/dS1 , T * + // dPc2/dS2 } } } // *** upwinding *** - // compute potential gradient real64 potGrad = presGrad[ip] - gravHead[ip]; // DPhi = T (P1 - P2) - T rho g (z1 - z2) if( m_hasCapPressure ) @@ -1085,35 +2361,39 @@ class FluxComputeInterfaceConditionKernel : public FluxComputeKernel< NUM_EQN, N // compute upwinding tolerance real64 constexpr upwRelTol = 1e-8; real64 const upwAbsTol = fmax( potScale * upwRelTol, LvArray::NumericLimits< real64 >::epsilon ); // abstol = maxPhi * tol > eps ? - // maxPhi * tol : eps + // maxPhi * tol : eps // decide mobility coefficients - smooth variation in [-upwAbsTol; upwAbsTol] - real64 alpha = ( potGrad + upwAbsTol ) / ( 2 * upwAbsTol ); // alpha = (DPhi + abstol) / abstol / 2 + real64 alpha = ( potGrad + upwAbsTol ) / ( 2 * upwAbsTol ); // alpha = (DPhi + abstol) / abstol / 2 // choose upstream cell - if( alpha <= 0.0 || alpha >= 1.0 ) // no smoothing needed + if( alpha <= 0.0 || alpha >= 1.0 ) // no smoothing needed { localIndex const k_up = 1 - localIndex( fmax( fmin( alpha, 1.0 ), 0.0 ) ); // 1 upwind -> k_up = 0 || 2 upwind -> k_up = 1 - mobility[ip] = m_mob[seri[k_up]][sesri[k_up]][sei[k_up]][ip]; // M = Mupstream - density2[ip] = m_dens[seri[k_up]][sesri[k_up]][sei[k_up]][0][ip]; // r = rho1 || rho2 - dDens_dP2[ip][k_up] = m_dDens_dPres[seri[k_up]][sesri[k_up]][sei[k_up]][0][ip][Deriv::dP]; // dr/dP = dr1/dP1 || dr2/dP - dMob_dP[ip][k_up] = m_dMob[seri[k_up]][sesri[k_up]][sei[k_up]][ip][Deriv::dP]; // dM/dP = {dM/dP1 , 0} OR {0 , dM/dP2} - dMob_dS[ip][k_up] = m_dMob[seri[k_up]][sesri[k_up]][sei[k_up]][ip][Deriv::dS]; // dM/dS = {dM/dS1 , 0} OR {0 , dM/dS2} + mobility[ip] = m_mob[seri[k_up]][sesri[k_up]][sei[k_up]][ip]; // M = Mupstream + density2[ip] = m_dens[seri[k_up]][sesri[k_up]][sei[k_up]][0][ip]; // r = rho1 || rho2 + dDens_dP2[ip][k_up] = m_dDens_dPres[seri[k_up]][sesri[k_up]][sei[k_up]][0][ip][Deriv::dP]; // dr/dP = dr1/dP1 || dr2/dP + viscosity[ip] = m_visc[seri[k_up]][sesri[k_up]][sei[k_up]][0][ip]; + dVisc_dP[ip][k_up] = m_dVisc_dPres[seri[k_up]][sesri[k_up]][sei[k_up]][0][ip][Deriv::dP]; + dMob_dP[ip][k_up] = m_dMob[seri[k_up]][sesri[k_up]][sei[k_up]][ip][Deriv::dP]; // dM/dP = {dM/dP1 , 0} OR {0 , dM/dP2} + dMob_dS[ip][k_up] = m_dMob[seri[k_up]][sesri[k_up]][sei[k_up]][ip][Deriv::dS]; // dM/dS = {dM/dS1 , 0} OR {0 , dM/dS2} } - else // perform smoothing + else // perform smoothing { real64 const mobWeights[2] = { alpha, 1.0 - alpha }; for( integer ke = 0; ke < 2; ++ke ) { - mobility[ip] += mobWeights[ke] * m_mob[seri[ke]][sesri[ke]][sei[ke]][ip]; // M = alpha * M1 + (1 - alpha) * M2 - density2[ip] += mobWeights[ke] * m_dens[seri[ke]][sesri[ke]][sei[ke]][0][ip]; // r = rho1 || rho2 - dDens_dP2[ip][ke] = mobWeights[ke] * m_dDens_dPres[seri[ke]][sesri[ke]][sei[ke]][0][ip][Deriv::dP]; // dr/dP = dr1/dP1 || - // dr2/dP + mobility[ip] += mobWeights[ke] * m_mob[seri[ke]][sesri[ke]][sei[ke]][ip]; // M = alpha * M1 + (1 - alpha) * M2 + density2[ip] += mobWeights[ke] * m_dens[seri[ke]][sesri[ke]][sei[ke]][0][ip]; // r = rho1 || rho2 + dDens_dP2[ip][ke] = mobWeights[ke] * m_dDens_dPres[seri[ke]][sesri[ke]][sei[ke]][0][ip][Deriv::dP]; // dr/dP = dr1/dP1 || + // dr2/dP + viscosity[ip] = m_visc[seri[ke]][sesri[ke]][sei[ke]][0][ip]; + dVisc_dP[ip][ke] = m_dVisc_dPres[seri[ke]][sesri[ke]][sei[ke]][0][ip][Deriv::dP]; dMob_dP[ip][ke] = mobWeights[ke] * m_dMob[seri[ke]][sesri[ke]][sei[ke]][ip][Deriv::dP]; // dM/dP = {alpha * dM1/dP1 , (1 - - // alpha) * dM2/dP2} + // alpha) * dM2/dP2} dMob_dS[ip][ke] = mobWeights[ke] * m_dMob[seri[ke]][sesri[ke]][sei[ke]][ip][Deriv::dS]; // dM/dP = {alpha * dM1/dS1 , (1 - - // alpha) * dM2/dS2} + // alpha) * dM2/dS2} } } @@ -1121,16 +2401,16 @@ class FluxComputeInterfaceConditionKernel : public FluxComputeKernel< NUM_EQN, N for( integer ke = 0; ke < 2; ++ke ) { dFlux_dP[ip][ke] += dPresGrad_dP[ip][ke]; // dF/dP = { T + dT/dP1 * (P1 - P2) , - // -T + dT/dP2 * (P1 - P2) } + // -T + dT/dP2 * (P1 - P2) } } // gravitational head depends only on the two cells connected (same as mean density) for( integer ke = 0; ke < 2; ++ke ) { dFlux_dP[ip][ke] -= dGravHead_dP[ip][ke]; // dF/dP = { T + dT/dP1 * (P1 - P2) - drho/dP1 * T g (z1 - z2) - dT/dP1 * rho g (z1 - - // z2) , - // -T + dT/dP2 * (P1 - P2) - drho/dP2 * T g (z1 - z2) - dT/dP2 * rho g (z1 - - // z2) } + // z2) , + // -T + dT/dP2 * (P1 - P2) - drho/dP2 * T g (z1 - z2) - dT/dP2 * rho g (z1 - + // z2) } } // capillary pressure contribution @@ -1138,12 +2418,12 @@ class FluxComputeInterfaceConditionKernel : public FluxComputeKernel< NUM_EQN, N { for( integer ke = 0; ke < 2; ++ke ) { - dFlux_dP[ip][ke] += dCapGrad_dP[ip][ke]; // dF/dP = { T + dT/dP1 * (P1 - P2) - drho/dP1 * T g (z1 - z2) - dT/dP1 * rho g (z1 - // - z2) + dT/dP1 * (-Pc1 + Pc2) , - // -T + dT/dP2 * (P1 - P2) - drho/dP2 * T g (z1 - z2) - dT/dP2 * rho g (z1 - // - z2) + dT/dP2 * (-Pc1 + Pc2) } + dFlux_dP[ip][ke] += dCapGrad_dP[ip][ke]; // dF/dP = { T + dT/dP1 * (P1 - P2) - drho/dP1 * T g (z1 - z2) - dT/dP1 * rho g (z1 + // - z2) + dT/dP1 * (-Pc1 + Pc2) , + // -T + dT/dP2 * (P1 - P2) - drho/dP2 * T g (z1 - z2) - dT/dP2 * rho g (z1 + // - z2) + dT/dP2 * (-Pc1 + Pc2) } - dFlux_dS[ip][ke] += dCapGrad_dS[ip][ke]; // dF/dS = { T * -dPc/dS1 , T * dPc/dS2 } + dFlux_dS[ip][ke] += dCapGrad_dS[ip][ke]; // dF/dS = { T * -dPc/dS1 , T * dPc/dS2 } } } @@ -1152,534 +2432,260 @@ class FluxComputeInterfaceConditionKernel : public FluxComputeKernel< NUM_EQN, N for( integer ke = 0; ke < 2; ++ke ) { - dFlux_dP[ip][ke] *= mobility[ip]; // dF/dP = { M [ T + dT/dP1 * (P1 - P2) - drho/dP1 * T g (z1 - z2) - dT/dP1 * rho g (z1 - - // z2) + dT/dP1 * (-Pc1 + Pc2)] , - // M [-T + dT/dP2 * (P1 - P2) - drho/dP2 * T g (z1 - z2) - dT/dP2 * rho g (z1 - - // z2) + dT/dP2 * (-Pc1 + Pc2)] } + dFlux_dP[ip][ke] *= mobility[ip]; // dF/dP = { M [ T + dT/dP1 * (P1 - P2) - drho/dP1 * T g (z1 - z2) - dT/dP1 * rho g (z1 - + // z2) + dT/dP1 * (-Pc1 + Pc2)] , + // M [-T + dT/dP2 * (P1 - P2) - drho/dP2 * T g (z1 - z2) - dT/dP2 * rho g (z1 - + // z2) + dT/dP2 * (-Pc1 + Pc2)] } - dFlux_dS[ip][ke] *= mobility[ip]; // dF/dS = { M [T * -dPc/dS1] , M [T * dPc/dS2] } + dFlux_dS[ip][ke] *= mobility[ip]; // dF/dS = { M [T * -dPc/dS1] , M [T * dPc/dS2] } } // add contribution from upstream cell mobility derivatives for( integer ke = 0; ke < 2; ++ke ) { - dFlux_dP[ip][ke] += dMob_dP[ip][ke] * potGrad; // dF/dP = { M [ T + dT/dP1 * (P1 - P2) - drho1/dP * T g (z1 - z2) - dT/dP1 * - // rho g (z1 - z2) + dT/dP1 * (-Pc1 + Pc2)] + dM/dP1 * DPhi , - // M [-T + dT/dP2 * (P1 - P2) - drho2/dP * T g (z1 - z2) - dT/dP2 * - // rho g (z1 - z2) + dT/dP2 * (-Pc1 + Pc2)] + dM/dP2 * DPhi } - dFlux_dS[ip][ke] += dMob_dS[ip][ke] * potGrad; // dF/dS = { M [T * -dPc/dS1] + dM/dS1 * DPhi , M [T * dPc/dS2] + dM/dS2 * DPhi - // } + + real64 dMob_dP2 = mobility[ip] / density2[ip] * (-dVisc_dP[ip][ke] / viscosity[ip]); + + duT_dP[ke] += dFlux_dP[ip][ke] / density2[ip] + dMob_dP2 * potGrad; + + dFlux_dP[ip][ke] += dMob_dP[ip][ke] * potGrad; // dF/dP = { M [ T + dT/dP1 * (P1 - P2) - drho1/dP * T g (z1 - z2) - dT/dP1 * + // rho g (z1 - z2) + dT/dP1 * (-Pc1 + Pc2)] + dM/dP1 * DPhi , + // M [-T + dT/dP2 * (P1 - P2) - drho2/dP * T g (z1 - z2) - dT/dP2 * + // rho g (z1 - z2) + dT/dP2 * (-Pc1 + Pc2)] + dM/dP2 * DPhi } + dFlux_dS[ip][ke] += dMob_dS[ip][ke] * potGrad; // dF/dS = { M [T * -dPc/dS1] + dM/dS1 * DPhi , M [T * dPc/dS2] + dM/dS2 * DPhi + // } } + uT += fluxVal[ip] / density2[ip]; // add contribution from upstream cell mobility derivatives for( integer ke = 0; ke < 2; ++ke ) { - duT_dP[ke] += dFlux_dP[ip][ke] - fluxVal[ip] * dDens_dP2[ip][ke] / density2[ip]; - - duT_dP[ke] /= density2[ip]; - duT_dS[ke] += dFlux_dS[ip][ke] / density2[ip]; +// duT_dP[ke] += dFlux_dP[ip][ke] - fluxVal[ip] * dDens_dP2[ip][ke] / density2[ip]; +// // duT_dP[ke] += dFlux_dP[ip][ke]; + +// duT_dP[ke] /= density2[ip]; + + duT_dS[ke] += dFlux_dS[ip][ke] / density2[ip]; + // duT_dS[ke] += dFlux_dS[ip][ke]; + } potGrad_ip[ip] = potGrad; alpha_ip[ip] = alpha; } // loop over phases - // std::cout << GEOS_FMT( " Pc1 = ( {:4.2e} )", capPresIC[1][0] ); - // std::cout << GEOS_FMT( " Pc2 = ( {:4.2e} )", capPresIC[1][1] ); - if (std::fabs(jFMultiplier[0][0] - jFMultiplier[0][1]) < 1e-8 && std::fabs(jFMultiplier[1][0] - jFMultiplier[1][1]) < 1e-8 ) { - for( integer ip = 0; ip < 2; ++ip ) { - // populate local flux vector and derivatives - stack.localFlux[k[0]*numEqn + ip] += m_dt * fluxVal[ip]; - stack.localFlux[k[1]*numEqn + ip] -= m_dt * fluxVal[ip]; - - for( integer ke = 0; ke < 2; ++ke ) + // this determines whether the local solver is needed becuase of heterogeneous capillary pressure regions + bool notOnInterface = std::fabs( jFMultiplier[0][0] - jFMultiplier[0][1] ) < 1 && std::fabs( jFMultiplier[1][0] - jFMultiplier[1][1] ) < 1; + notOnInterface = !connectorHasInterfaceConditionQ; + if( notOnInterface ) + { + for( integer ip = 0; ip < 2; ++ip ) { - // pressure - localIndex const localDofIndexPres = k[ke] * numDof; - stack.localFluxJacobian[k[0]*numEqn + ip][localDofIndexPres] += m_dt * dFlux_dP[ip][ke]; - stack.localFluxJacobian[k[1]*numEqn + ip][localDofIndexPres] -= m_dt * dFlux_dP[ip][ke]; - - // saturation (hard-coded for 2-phase currently) - localIndex const localDofIndexSat = k[ke] * numDof + 1; - stack.localFluxJacobian[k[0]*numEqn + ip][localDofIndexSat] += m_dt * dFlux_dS[ip][ke]; - stack.localFluxJacobian[k[1]*numEqn + ip][localDofIndexSat] -= m_dt * dFlux_dS[ip][ke]; - } + // populate local flux vector and derivatives + stack.localFlux[k[0]*numEqn + ip] += m_dt * fluxVal[ip]; + stack.localFlux[k[1]*numEqn + ip] -= m_dt * fluxVal[ip]; - // Customize the kernel with this lambda - kernelOp( k, seri, sesri, sei, connectionIndex, alpha_ip[ip], mobility, potGrad_ip[ip], fluxVal, dFlux_dP, dFlux_dS ); // Not sure what this - - }// does - } else { + for( integer ke = 0; ke < 2; ++ke ) + { + // pressure + localIndex const localDofIndexPres = k[ke] * numDof; + stack.localFluxJacobian[k[0]*numEqn + ip][localDofIndexPres] += m_dt * dFlux_dP[ip][ke]; + stack.localFluxJacobian[k[1]*numEqn + ip][localDofIndexPres] -= m_dt * dFlux_dP[ip][ke]; + + // saturation + localIndex const localDofIndexSat = k[ke] * numDof + 1; + stack.localFluxJacobian[k[0]*numEqn + ip][localDofIndexSat] += m_dt * dFlux_dS[ip][ke]; + stack.localFluxJacobian[k[1]*numEqn + ip][localDofIndexSat] -= m_dt * dFlux_dS[ip][ke]; + } - - + // Customize the kernel with this lambda + kernelOp( k, seri, sesri, sei, connectionIndex, alpha_ip[ip], mobility, potGrad_ip[ip], fluxVal, dFlux_dP, dFlux_dS ); + } + } + else + { - // -------------------- Here I implement the interface conditions local solver --------------------- // // nonlinear solver's parameters - real64 tol = 1.0e-7; - int max_iter = 20; - - // initial guess: - real64 S_int[numEqn]{}; - real64 const Pc1 = capPresIC[1][0]; - real64 const Pc2 = capPresIC[1][1]; - - real64 Pc_int = ( Pc1 + Pc2 ) / 2; - // std::cout << GEOS_FMT( " Pc_int_old = ( {:4.2e} )", Pc_int ); - // // Local newton loop: + real64 tol = 1.0e-9; + int max_iter = 50; + bool converged = 0; + bool damping = true; + // Local newton loop: // Use of the capillary pressure kernel wrapper - - StackArray< real64, 2, 2, immiscibleFlow::LAYOUT_PHASE > facePhaseVolFrac1( 1, 2 ); - StackArray< real64, 3, 2, constitutive::cappres::LAYOUT_CAPPRES > faceCapPres1( 1, 1, 2 ); - StackArray< real64, 4, 4, constitutive::cappres::LAYOUT_CAPPRES_DS > dfacePhaseVolFrac_dCapPres1( 1, 1, 2, 2 ); - StackArray< real64, 4, 4, constitutive::cappres::LAYOUT_CAPPRES_DS > dCapPres1_dfacePhaseVolFrac( 1, 1, 2, 2 ); - StackArray< real64, 2, 2, immiscibleFlow::LAYOUT_PHASE > facePhaseVolFrac2( 1, 2 ); - StackArray< real64, 3, 2, constitutive::cappres::LAYOUT_CAPPRES > faceCapPres2( 1, 1, 2 ); - StackArray< real64, 4, 4, constitutive::cappres::LAYOUT_CAPPRES_DS > dfacePhaseVolFrac_dCapPres2( 1, 1, 2, 2 ); - StackArray< real64, 4, 4, constitutive::cappres::LAYOUT_CAPPRES_DS > dCapPres2_dfacePhaseVolFrac( 1, 1, 2, 2 ); - StackArray< real64, 1, 4> JFunc1( 2 ); - StackArray< real64, 1, 4> JFunc2( 2 ); - - JFunc1[0] = jFMultiplier[0][0]; - JFunc2[0] = jFMultiplier[0][1]; - - // finding endpoints: - facePhaseVolFrac1[0][0] = 0.0; - facePhaseVolFrac1[0][1] = 1.0; - m_capPressureWrapper.compute( facePhaseVolFrac1[0], - JFunc1.toSliceConst(), - faceCapPres1[0][0], - dCapPres1_dfacePhaseVolFrac[0][0]); - real64 const Pc1_min = faceCapPres1[0][0][1]; - facePhaseVolFrac1[0][0] = 1.0; - facePhaseVolFrac1[0][1] = 0.0; - m_capPressureWrapper.compute( facePhaseVolFrac1[0], - JFunc1.toSliceConst(), - faceCapPres1[0][0], - dCapPres1_dfacePhaseVolFrac[0][0]); - real64 const Pc1_max = faceCapPres1[0][0][1]; - - facePhaseVolFrac2[0][0] = 0.0; - facePhaseVolFrac2[0][1] = 1.0; - m_capPressureWrapper.compute( facePhaseVolFrac2[0], - JFunc2.toSliceConst(), - faceCapPres2[0][0], - dCapPres2_dfacePhaseVolFrac[0][0]); - real64 const Pc2_min = faceCapPres2[0][0][1]; - facePhaseVolFrac2[0][0] = 1.0; - facePhaseVolFrac2[0][1] = 0.0; - m_capPressureWrapper.compute( facePhaseVolFrac2[0], - JFunc2.toSliceConst(), - faceCapPres2[0][0], - dCapPres2_dfacePhaseVolFrac[0][0]); - real64 const Pc2_max = faceCapPres2[0][0][1]; - - - std::cout << GEOS_FMT( " Pc_max1 = ( {:4.2e} )", Pc1_max ); - std::cout << GEOS_FMT( " Pc_min1 = ( {:4.2e} )", Pc1_min ); - std::cout << GEOS_FMT( " Pc_max2 = ( {:4.2e} )", Pc2_max ); - std::cout << GEOS_FMT( " Pc_min2 = ( {:4.2e} )", Pc2_min ); + StackArray< real64, 2, 2, immiscibleFlow::LAYOUT_PHASE > facePhaseVolFrac1( 1, 2 ); + StackArray< real64, 3, 2, constitutive::cappres::LAYOUT_CAPPRES > faceCapPres1( 1, 1, 2 ); + StackArray< real64, 4, 4, constitutive::cappres::LAYOUT_CAPPRES_DS > dfacePhaseVolFrac_dCapPres1( 1, 1, 2, 2 ); + StackArray< real64, 4, 4, constitutive::cappres::LAYOUT_CAPPRES_DS > dCapPres1_dfacePhaseVolFrac( 1, 1, 2, 2 ); + StackArray< real64, 2, 2, immiscibleFlow::LAYOUT_PHASE > facePhaseVolFrac2( 1, 2 ); + StackArray< real64, 3, 2, constitutive::cappres::LAYOUT_CAPPRES > faceCapPres2( 1, 1, 2 ); + StackArray< real64, 4, 4, constitutive::cappres::LAYOUT_CAPPRES_DS > dfacePhaseVolFrac_dCapPres2( 1, 1, 2, 2 ); + StackArray< real64, 4, 4, constitutive::cappres::LAYOUT_CAPPRES_DS > dCapPres2_dfacePhaseVolFrac( 1, 1, 2, 2 ); + StackArray< real64, 1, 2 > JFunc1( 2 ); + StackArray< real64, 1, 2 > JFunc2( 2 ); + + JFunc1[0] = jFMultiplier[0][0]; + JFunc2[0] = jFMultiplier[0][1]; + + // finding endpoints: + facePhaseVolFrac1[0][1] = 0.0; + facePhaseVolFrac1[0][0] = 1.0; + m_capPressureWrapper.compute( facePhaseVolFrac1[0], + JFunc1.toSliceConst(), + faceCapPres1[0][0], + dCapPres1_dfacePhaseVolFrac[0][0] ); + real64 const Pc1_min = faceCapPres1[0][0][0]; + facePhaseVolFrac1[0][1] = 1.0; + facePhaseVolFrac1[0][0] = 0.0; + m_capPressureWrapper.compute( facePhaseVolFrac1[0], + JFunc1.toSliceConst(), + faceCapPres1[0][0], + dCapPres1_dfacePhaseVolFrac[0][0] ); + real64 const Pc1_max = faceCapPres1[0][0][0]; + + facePhaseVolFrac2[0][1] = 0.0; + facePhaseVolFrac2[0][0] = 1.0; + m_capPressureWrapper.compute( facePhaseVolFrac2[0], + JFunc2.toSliceConst(), + faceCapPres2[0][0], + dCapPres2_dfacePhaseVolFrac[0][0] ); + real64 const Pc2_min = faceCapPres2[0][0][0]; + facePhaseVolFrac2[0][1] = 1.0; + facePhaseVolFrac2[0][0] = 0.0; + m_capPressureWrapper.compute( facePhaseVolFrac2[0], + JFunc2.toSliceConst(), + faceCapPres2[0][0], + dCapPres2_dfacePhaseVolFrac[0][0] ); + real64 const Pc2_max = faceCapPres2[0][0][0]; // Use of the relative permeability kernel wrapper - - StackArray< real64, 3, 2, constitutive::relperm::LAYOUT_RELPERM > faceTrappedVolFrac1( 1, 1, 2 ); - StackArray< real64, 3, 2, constitutive::relperm::LAYOUT_RELPERM > faceRelPerm1( 1, 1, 2 ); - StackArray< real64, 4, 4, constitutive::relperm::LAYOUT_RELPERM_DS > dfacePhaseRelPerm1_dPhaseVolFrac( 1, 1, 2, 2 ); - StackArray< real64, 3, 2, constitutive::relperm::LAYOUT_RELPERM > faceTrappedVolFrac2( 1, 1, 2 ); - StackArray< real64, 3, 2, constitutive::relperm::LAYOUT_RELPERM > faceRelPerm2( 1, 1, 2 ); - StackArray< real64, 4, 4, constitutive::relperm::LAYOUT_RELPERM_DS > dfacePhaseRelPerm2_dPhaseVolFrac( 1, 1, 2, 2 ); - - real64 halfFluxVal[numEqn][2]{}; - real64 dhalfFlux_dP[numEqn][4]{}; - real64 dhalfFlux_dS[numEqn][4]{}; - real64 dhalfFlux_duT[numEqn][2]{}; - - // While loop - int iter = 0; - - - while (iter < max_iter) { - - - - - real64 density[numEqn]{}; - real64 dDens_dP[numEqn][2]{}; - real64 viscosity[numEqn]{}; - real64 dVisc_dP[numEqn][2]{}; - - - real64 local_residual = 0; - real64 local_jacobian = 0; - - real64 Pc_int1 = fmin(Pc1_max, fmax(Pc_int, Pc1_min)); - real64 Pc_int2 = fmin(Pc2_max, fmax(Pc_int, Pc2_min)); - - // std::cout << GEOS_FMT( " Pc_int1 = ( {:4.2e} )", Pc_int1 ); - // std::cout << GEOS_FMT( " Pc_int2 = ( {:4.2e} )", Pc_int2 ); - - // Compute the inverse using pc tilde:: - faceCapPres1[0][0][1] = fmin(Pc2_max, fmax(Pc_int1, Pc2_min)); - faceCapPres2[0][0][1] = fmin(Pc1_max, fmax(Pc_int2, Pc1_min)); + StackArray< real64, 3, 2, constitutive::relperm::LAYOUT_RELPERM > faceTrappedVolFrac1( 1, 1, 2 ); + StackArray< real64, 3, 2, constitutive::relperm::LAYOUT_RELPERM > faceRelPerm1( 1, 1, 2 ); + StackArray< real64, 4, 4, constitutive::relperm::LAYOUT_RELPERM_DS > dfacePhaseRelPerm1_dPhaseVolFrac( 1, 1, 2, 2 ); + StackArray< real64, 3, 2, constitutive::relperm::LAYOUT_RELPERM > faceTrappedVolFrac2( 1, 1, 2 ); + StackArray< real64, 3, 2, constitutive::relperm::LAYOUT_RELPERM > faceRelPerm2( 1, 1, 2 ); + StackArray< real64, 4, 4, constitutive::relperm::LAYOUT_RELPERM_DS > dfacePhaseRelPerm2_dPhaseVolFrac( 1, 1, 2, 2 ); + + // clear working arrays + real64 halfFluxVal[numEqn][2]{}; + real64 dhalfFlux1_dP[numEqn][2]{}; + real64 dhalfFlux1_dS[numEqn][2]{}; + real64 dhalfFlux2_dP[numEqn][2]{}; + real64 dhalfFlux2_dS[numEqn][2]{}; + real64 dhalfFlux_duT[numEqn][2]{}; + real64 dhalfFlux_dpc[numEqn][2]{}; + // initial guess: + real64 S_int[numEqn]{}; + real64 const Pc1 = capPresIC[0][0]; + real64 const Pc2 = capPresIC[0][1]; - std::cout << GEOS_FMT( " faceCapPres1[0][0][1] = ( {:4.2e} )", faceCapPres1[0][0][1] ); - std::cout << GEOS_FMT( " faceCapPres2[0][0][1] = ( {:4.2e} )", faceCapPres2[0][0][1] ); - - std::cout << GEOS_FMT( " faceCapPres1[0][0][0] = ( {:4.2e} )", faceCapPres1[0][0][0] ); - std::cout << GEOS_FMT( " faceCapPres2[0][0][0] = ( {:4.2e} )", faceCapPres2[0][0][0] ); - - - - m_capPressureWrapper.computeInv( facePhaseVolFrac1[0], - JFunc1.toSliceConst(), - faceCapPres1[0][0], - dfacePhaseVolFrac_dCapPres1[0][0]); - - m_capPressureWrapper.computeInv( facePhaseVolFrac2[0], - JFunc2.toSliceConst(), - faceCapPres2[0][0], - dfacePhaseVolFrac_dCapPres2[0][0]); - - // compute relative permeability for both cells: - m_relPermWrapper.compute( facePhaseVolFrac1[0], - faceTrappedVolFrac1[0][0], - faceRelPerm1[0][0], - dfacePhaseRelPerm1_dPhaseVolFrac[0][0]); - - m_relPermWrapper.compute( facePhaseVolFrac2[0], - faceTrappedVolFrac2[0][0], - faceRelPerm2[0][0], - dfacePhaseRelPerm2_dPhaseVolFrac[0][0]); - - - // real64 Sw_alpha = facePhaseVolFrac1[0][1]; - // real64 Sw_beta = facePhaseVolFrac2[0][1]; - // // std::cout << GEOS_FMT( " Sw_alpha = ( {:4.2e} )", Sw_alpha ); - // // std::cout << GEOS_FMT( " Sw_beta = ( {:4.2e} )", Sw_beta ); - - // real64 Sn_alpha = facePhaseVolFrac1[0][0]; - // real64 Sn_beta = facePhaseVolFrac2[0][0]; - - - //get derivatives: - m_capPressureWrapper.compute( facePhaseVolFrac1[0], - JFunc1.toSliceConst(), - faceCapPres1[0][0], - dCapPres1_dfacePhaseVolFrac[0][0]); - - m_capPressureWrapper.compute( facePhaseVolFrac2[0], - JFunc1.toSliceConst(), - faceCapPres2[0][0], - dCapPres2_dfacePhaseVolFrac[0][0]); - - - - - - for( integer ix = 0; ix < 2; ++ix ) // for loop over each half flux - { - // loop over phases - // clear arrays: - presGrad[0] = 0; - presGrad[1] = 0; - gravHead[0] = 0; - gravHead[1] = 0; - dGravHead_dP[0][0] = 0; - dGravHead_dP[0][1] = 0; - dGravHead_dP[1][0] = 0; - dGravHead_dP[1][1] = 0; - capGrad[0] = 0; - capGrad[1] = 0; - dCapGrad_dP[0][0] = 0; - dCapGrad_dP[1][0] = 0; - dCapGrad_dP[0][1] = 0; - dCapGrad_dP[1][1] = 0; - - for( integer ip = 0; ip < m_numPhases; ++ip ) - { - // calculate quantities on primary connected cells - // density - density[ip] = m_dens[seri[ix]][sesri[ix]][sei[ix]][0][ip]; // r = rho1 || rho2 - dDens_dP[ip][ix] = m_dDens_dPres[seri[ix]][sesri[ix]][sei[ix]][0][ip][Deriv::dP]; // dr/dP = dr1/dP1 || dr2/dP - - viscosity[ip] = m_visc[seri[ix]][sesri[ix]][sei[ix]][0][ip]; // r = rho1 || rho2 - dVisc_dP[ip][ix] = m_dVisc_dPres[seri[ix]][sesri[ix]][sei[ix]][0][ip][Deriv::dP]; // dr/dP = dr1/dP1 || dr2/dP - - densMean[ip] = density[ip]; // rho = (rho1 + rho2) - dDensMean_dP[ip][0] = dDens_dP[ip][ix]; // drho/dP = { (dr1/dP1) , (dr2/dP2) } - dDensMean_dP[ip][1] = dDens_dP[ip][ix]; - - //***** calculation of flux ***** - - // compute potential difference - real64 potScale = 0.0; - real64 dPresGrad_dTrans = 0.0; - real64 dGravHead_dTrans = 0.0; - real64 dCapGrad_dTrans = 0.0; - constexpr int signPotDiff[2] = {1, -1}; - - for( integer ke = 0; ke < 2; ++ke ) - { - localIndex const er = seri[ke]; - localIndex const esr = sesri[ke]; - localIndex const ei = sei[ke]; - - real64 const pressure = m_pres[er][esr][ei]; // P = P1 || P2 - presGrad[ip] += transHat[ix] * pressure; // DPv = T (P1 - P2) - dPresGrad_dTrans += signPotDiff[ke] * pressure; // dDPv/dT = (P1 - P2) - dPresGrad_dP[ip][ke] = transHat[ix]; // dDPv/dP = { T , -T } - - real64 const gravD = transHat[ix] * gravCoefHat[ix]; // D = T g z1 || -T g z2 - real64 pot = transHat[ix] * pressure - densMean[ip] * gravD; // Phi = T P1 - rho T g z1 || -T P2 + rho T g z2 - - gravHead[ip] += densMean[ip] * gravD; // DPg = rho (T g z1 - T g z2) = T rho g (z1 - z2) - dGravHead_dTrans += signPotDiff[ke] * densMean[ip] * gravCoefHat[ix]; // dDPg/dT = rho g z1 - rho g z2 = rho g (z1 - z2) - - for( integer i = 0; i < 2; ++i ) - { - dGravHead_dP[ip][i] += dDensMean_dP[ip][i] * gravD; // dDPg/dP = {drho/dP1 * T g (z1 - z2) , drho/dP2 * T g (z1 - z2)} - } - - if( m_hasCapPressure ) // check sign convention - { - real64 capPres = m_phaseCapPressure[seri[ix]][sesri[ix]][sei[ix]][0][ip]; // Pc = Pc1 || Pc2 - - if( ke == 1 && ix == 0 ) { - capPres = faceCapPres1[0][0][ip]; - } else if ( ke == 1 && ix == 1 ) { - capPres = faceCapPres2[0][0][ip]; - } - - dCapGrad_dTrans -= signPotDiff[ke] * capPres; // dDPc/dT = (-Pc1 + Pc2) - pot -= transHat[ix] * capPres; // Phi = T P1 - rho T g z1 - T Pc1 || -T P2 + rho T g z2 + T - // Pc2 - capGrad[ip] -= transHat[ix] * capPres; // DPc = T (-Pc1 + Pc2) - } + real64 Pc_int = ( Pc1 + Pc2 ) / 2.0; - potScale = fmax( potScale, fabs( pot ) ); // maxPhi = Phi1 > Phi2 ? Phi1 : Phi2 - } + real64 Pc_min_all = fmax( Pc1_min, Pc2_min ); + real64 Pc_max_all = fmin( Pc1_max, Pc2_max ); - for( integer ke = 0; ke < 2; ++ke ) - { - dPresGrad_dP[ip][ke] += dTransHat_dP[ix] * dPresGrad_dTrans; // dDPv/dP = { T + dT/dP1 * (P1 - P2) , -T + dT/dP2 * (P1 - P2)} - dGravHead_dP[ip][ke] += dTransHat_dP[ix] * dGravHead_dTrans; // dDPg/dP = { drho/dP1 * T g (z1 - z2) + dT/dP1 * rho g (z1 - z2) , - // drho/dP2 * T g (z1 - z2) + dT/dP2 * rho g (z1 - z2) } - if( m_hasCapPressure ) + if( Pc_int < Pc_min_all || Pc_int > Pc_max_all ) { - real64 constexpr eps = 1e-8; - real64 dCapPres_dS = m_dPhaseCapPressure_dPhaseVolFrac[seri[ix]][sesri[ix]][sei[ix]][0][ip][ip]; // dPc/dS = dPc1/dS1 || - - - if( ke == 1 && ix == 0 ) { - dCapPres_dS = dCapPres1_dfacePhaseVolFrac[0][0][ip][ip]; - } else if ( ke == 1 && ix == 1 ) { - dCapPres_dS = dCapPres2_dfacePhaseVolFrac[0][0][ip][ip]; - } - // dPc2/dS2 - dCapGrad_dP[ip][ke] += dTransHat_dP[ix] * dCapGrad_dTrans; // dDPc/dP = { dT/dP1 * - // (-Pc1 + Pc2) , - // dT/dP2 * - // (-Pc1 + Pc2) } - dCapGrad_dS[ip][ke] -= transHat[ix] * dCapPres_dS; // dDPc/dS = { -T * - // dPc1/dS1 , T * - // dPc2/dS2 } + Pc_int = ( Pc_min_all + Pc_max_all ) / 2.0; } - } - - // *** upwinding *** - - // compute potential gradient - real64 potGrad = presGrad[ip] - gravHead[ip]; // DPhi = T (P1 - P2) - T rho g (z1 - z2) - if( m_hasCapPressure ) - { - potGrad += capGrad[ip]; // DPhi = T (P1 - P2) - T rho g (z1 - z2) + T (-Pc1 + Pc2) - } - - // compute upwinding tolerance - real64 constexpr upwRelTol = 1e-8; - real64 const upwAbsTol = fmax( potScale * upwRelTol, LvArray::NumericLimits< real64 >::epsilon ); // abstol = maxPhi * tol > eps ? - // maxPhi * tol : eps - - // decide mobility coefficients - smooth variation in [-upwAbsTol; upwAbsTol] - real64 const alpha = ( potGrad + upwAbsTol ) / ( 2 * upwAbsTol ); // alpha = (DPhi + abstol) / abstol / 2 - - // choose upstream cell - // if( alpha <= 0.0 || alpha >= 1.0 ) // no smoothing needed - // { - constexpr int sign[2] = {1, -1}; - - localIndex const k_up = 1 - localIndex( fmax( fmin( alpha, 1.0 ), 0.0 ) ); // 1 upwind -> k_up = 0 || 2 upwind -> k_up = 1 - - - if( k_up == 1 && ix == 0 ) { - - mobility[ip] = faceRelPerm1[0][0][ip] * density[ip] / viscosity[ip]; // M = Mupstream - dMob_dP[ip][k_up] = mobility[ip] * (dDens_dP[ip][ix] / density[ip] - dVisc_dP[ip][ix] / viscosity[ip]); // dM/dP = {dM/dP1 , 0} OR {0 , dM/dP2} - dMob_dS[ip][k_up] = dfacePhaseRelPerm1_dPhaseVolFrac[0][0][ip][ip] * density[ip] / viscosity[ip]; // dM/dS = {dM/dS1 , 0} OR {0 , dM/dS2} - } else if ( k_up == 1 && ix == 1 ) { - mobility[ip] = faceRelPerm2[0][0][ip] * density[ip] / viscosity[ip]; // M = Mupstream - dMob_dP[ip][k_up] = mobility[ip] * (dDens_dP[ip][ix] / density[ip] - dVisc_dP[ip][ix] / viscosity[ip]); // dM/dP = {dM/dP1 , 0} OR {0 , dM/dP2} - dMob_dS[ip][k_up] = dfacePhaseRelPerm2_dPhaseVolFrac[0][0][ip][ip] * density[ip] / viscosity[ip]; // dM/dS = {dM/dS1 , 0} OR {0 , dM/dS2} - } else { - mobility[ip] = m_mob[seri[k_up]][sesri[k_up]][sei[k_up]][ip]; // M = Mupstream - dMob_dP[ip][k_up] = m_dMob[seri[k_up]][sesri[k_up]][sei[k_up]][ip][Deriv::dP]; // dM/dP = {dM/dP1 , 0} OR {0 , dM/dP2} - dMob_dS[ip][k_up] = m_dMob[seri[k_up]][sesri[k_up]][sei[k_up]][ip][Deriv::dS]; // dM/dS = {dM/dS1 , 0} OR {0 , dM/dS2} - } - - - // } - // else // perform smoothing - // { - // real64 const mobWeights[2] = { alpha, 1.0 - alpha }; - // for( integer ke = 0; ke < 2; ++ke ) - // { - - // mobility[ip] += mobWeights[ke] * m_mob[seri[ke]][sesri[ke]][sei[ke]][ip]; // M = alpha * M1 + (1 - alpha) * M2 - // density2[ip] += mobWeights[ke] * m_dens[seri[ke]][sesri[ke]][sei[ke]][0][ip]; // r = rho1 || rho2 - // dDens_dP2[ip][ke] = mobWeights[ke] * m_dDens_dPres[seri[ke]][sesri[ke]][sei[ke]][0][ip][Deriv::dP]; // dr/dP = dr1/dP1 || - // // dr2/dP - // dMob_dP[ip][ke] = mobWeights[ke] * m_dMob[seri[ke]][sesri[ke]][sei[ke]][ip][Deriv::dP]; // dM/dP = {alpha * dM1/dP1 , (1 - - // // alpha) * dM2/dP2} - // dMob_dS[ip][ke] = mobWeights[ke] * m_dMob[seri[ke]][sesri[ke]][sei[ke]][ip][Deriv::dS]; // dM/dP = {alpha * dM1/dS1 , (1 - - // // alpha) * dM2/dS2} - // } - // } - real64 constexpr eps = 0.5e-8; - total_mobility += mobility[ip] + eps; - potGrad_ip[ip] = potGrad; - alpha_ip[ip] = alpha; - - } // loop over phases - /// Three Forces Flux Contribution: 1- Viscous 2- Gravitational 3- Capillary - constexpr int sign[2] = {1, -1}; - // loop over phases - for( integer ip = 0; ip < m_numPhases; ++ip ) - { - // 1- Viscous: pressure gradient depends on all points in the stencil - for( integer ke = 0; ke < 2; ++ke ) - { - halfFluxVal[ip][ix] = sign[0] * mobility[ip] / total_mobility * uT; - dhalfFlux_dP[ip][ix + ke] = sign[0] * sign[ip] * (dMob_dP[0][ke] * mobility[0] - dMob_dP[1][ke] * mobility[1]) / (total_mobility * total_mobility) * uT; // dF/dP = { T + dT/dP1 * (P1 - P2) , - // -T + dT/dP2 * (P1 - P2) } - dhalfFlux_dS[ip][ix + ke] = sign[0] * sign[ip] * (dMob_dS[0][ke] * mobility[0] - dMob_dS[1][ke] * mobility[1]) / (total_mobility * total_mobility) * uT; + real64 same_Pc_int = Pc_int; + + // GEOS_UNUSED_VAR(gravCoef2[0]); + // GEOS_UNUSED_VAR(gravCoef2[1]); + + // Pc_int = fmin( Pc_max_all, fmax( Pc_int, Pc_min_all )); + // m_interfaceConstitutivePairs[0][0] = std::make_tuple( relPerm, capPressure, fluid ); +// m_interfaceConstitutivePairs[0][1] = std::make_tuple( relPerm, capPressure, fluid ); + + stdVector< real64 > JFMultipliers = {jFMultiplier[0][0], jFMultiplier[0][1]}; + stdVector< real64 > trappedSats1 = {0.0, 0.0}; + stdVector< real64 > trappedSats2 = {0.0, 0.0}; + stdVector< real64 > transHats = {transHat[0], transHat[1]}; + stdVector< real64 > dTransHats_dP = {dTransHat_dP[0], dTransHat_dP[1]}; + stdVector< real64 > gravCoefHats = {gravCoefHat[0], gravCoefHat[1]}; + stdVector< real64 > gravCoefs = {gravCoef2[0], gravCoef2[1]}; + stdVector< real64 > cellCenterDuTdS = {duT_dP[0], duT_dP[1], duT_dS[0], duT_dS[1]}; + stdVector< real64 > cellCenterDens = {density2[0], density2[1]}; + stdVector< real64 > cellCenterDens_dP = {dDens_dP2[0][0], dDens_dP2[0][1], dDens_dP2[1][0], dDens_dP2[1][1]}; + std::vector< RelativePermeabilityBase * > relPerms = {std::get< 0 >( m_interfaceConstitutivePairs_temp ), std::get< 0 >( m_interfaceConstitutivePairs_temp )}; + std::vector< CapillaryPressureBase * > capPressures = {std::get< 1 >( m_interfaceConstitutivePairs_temp ), std::get< 1 >( m_interfaceConstitutivePairs_temp )}; + std::vector< TwoPhaseImmiscibleFluid * > fluids = {std::get< 2 >( m_interfaceConstitutivePairs_temp ), std::get< 2 >( m_interfaceConstitutivePairs_temp )}; + + stdVector< real64 > phi = {halfFluxVal[0][0], halfFluxVal[0][1]}; + stdVector< real64 > grad_phi_P = {0.0, 0.0, 0.0, 0.0}; + stdVector< real64 > grad_phi_S = {0.0, 0.0, 0.0, 0.0}; + + local_solver( uT, saturations, pressures, JFMultipliers, trappedSats1, trappedSats2, transHats, dTransHats_dP, gravCoefHats, gravCoefs, + cellCenterDuTdS, cellCenterDens, cellCenterDens_dP, relPerms, capPressures, fluids, phi, grad_phi_P, grad_phi_S, converged ); - } - // 2- Gravitational: gravitational head depends only on the two cells connected (same as mean density) - for( integer ke = 0; ke < 2; ++ke ) - { - halfFluxVal[ip][ix] -= mobility[0] * mobility[1] / total_mobility * gravHead[ip]; - - dhalfFlux_dP[ip][ix + ke] -= (dMob_dP[0][ke] * mobility[0] * mobility[0]+ dMob_dP[1][ke] * mobility[1] * mobility[1]) / (total_mobility * total_mobility) * gravHead[ip] + mobility[0] * mobility[1] / total_mobility * dGravHead_dP[ip][ke]; // dF/dP = { T + dT/dP1 * (P1 - P2) , - // -T + dT/dP2 * (P1 - P2) } - dhalfFlux_dS[ip][ix + ke] -= (dMob_dS[0][ke] * mobility[0] * mobility[0]+ dMob_dS[1][ke] * mobility[1] * mobility[1]) / (total_mobility * total_mobility) * gravHead[ip]; - } - - // 3- Capillary: capillary pressure contribution - - if( m_hasCapPressure ) - { - for( integer ke = 0; ke < 2; ++ke ) + fluxVal[0] = phi[0]; + fluxVal[1] = phi[1]; + dFlux_dP[0][0] = grad_phi_P[0]; + dFlux_dP[0][1] = grad_phi_P[1]; + dFlux_dP[1][0] = grad_phi_P[2]; + dFlux_dP[1][1] = grad_phi_P[3]; + dFlux_dS[0][0] = grad_phi_S[0]; + dFlux_dS[0][1] = grad_phi_S[1]; + dFlux_dS[1][0] = grad_phi_S[2]; + dFlux_dS[1][1] = grad_phi_S[3]; + + // Global residual and jacobian update: + for( integer ip = 0; ip < m_numPhases; ++ip ) { - halfFluxVal[ip][ix] -= sign[ip] * mobility[0] * mobility[1] / total_mobility * capGrad[1]; + // populate local flux vector and derivatives + stack.localFlux[k[0]*numEqn + ip] += m_dt * fluxVal[ip]; + stack.localFlux[k[1]*numEqn + ip] -= m_dt * fluxVal[ip]; - dhalfFlux_dP[ip][ix + ke] -= sign[ip] * (dMob_dP[0][ke] * mobility[0] * mobility[0]+ dMob_dP[1][ke] * mobility[1] * mobility[1]) / (total_mobility * total_mobility) * capGrad[1] + mobility[0] * mobility[1] / total_mobility * dCapGrad_dP[ip][ke]; // dF/dP = { T + dT/dP1 * (P1 - P2) , - // -T + dT/dP2 * (P1 - P2) } - dhalfFlux_dS[ip][ix + ke] -= sign[ip] * (dMob_dP[0][ke] * mobility[0] * mobility[0]+ dMob_dP[1][ke] * mobility[1] * mobility[1]) / (total_mobility * total_mobility) * capGrad[1] + mobility[0] * mobility[1] / total_mobility * dCapGrad_dS[ip][ke]; - } - } - - // does - - } // loop over phases - - } // loop over half fluxes - - local_jacobian = dhalfFlux_dS[1][1]*dfacePhaseVolFrac_dCapPres1[0][0][1][1] + dhalfFlux_dS[1][3]*dfacePhaseVolFrac_dCapPres2[0][0][1][1]; - local_residual = halfFluxVal[1][0] + halfFluxVal[1][1]; - - // // Write data to the file - // outFile << local_jacobian; - // outFile << ","; - // outFile << local_residual; - // outFile << ","; - // outFile << halfFluxVal[1][0]; - // outFile << ","; - // outFile << halfFluxVal[1][1]; - // outFile << ","; - // outFile << Pc_int; - // outFile << ","; - // outFile << iter; - // outFile << std::endl; - - if (std::fabs(local_jacobian) < 1e-16) { - std::cout << "Derivative is too small" << std::endl; - break; - } - - //std::cout << GEOS_FMT( " phase_mass = ( {:4.2e} )", phase_mass ); - real64 deltaPc = local_residual/local_jacobian; - - std::cout << GEOS_FMT( " local_R = ( {:4.2e} )", local_residual ); - std::cout << GEOS_FMT( " deltaPc = ( {:4.2e} )", deltaPc ); - - Pc_int -= deltaPc; - - - // Check convergence - if (std::fabs(local_residual) < tol) { - break; // Converged - } - - iter++; - } // while loop + for( integer ke = 0; ke < 2; ++ke ) + { + // pressure + localIndex const localDofIndexPres = k[ke] * numDof; + stack.localFluxJacobian[k[0]*numEqn + ip][localDofIndexPres] += m_dt * dFlux_dP[ip][ke]; + stack.localFluxJacobian[k[1]*numEqn + ip][localDofIndexPres] -= m_dt * dFlux_dP[ip][ke]; + + // saturation + localIndex const localDofIndexSat = k[ke] * numDof + 1; + stack.localFluxJacobian[k[0]*numEqn + ip][localDofIndexSat] += m_dt * dFlux_dS[ip][ke]; + stack.localFluxJacobian[k[1]*numEqn + ip][localDofIndexSat] -= m_dt * dFlux_dS[ip][ke]; + } - // // Close the file after writing - // outFile.close(); - for( integer ip = 0; ip < m_numPhases; ++ip ) - { - // populate local flux vector and derivatives - stack.localFlux[k[0]*numEqn + ip] += m_dt * (halfFluxVal[ip][0] + halfFluxVal[ip][1]); - stack.localFlux[k[1]*numEqn + ip] -= m_dt * (halfFluxVal[ip][0] + halfFluxVal[ip][1]); + // Customize the kernel with this lambda + kernelOp( k, seri, sesri, sei, connectionIndex, alpha_ip[ip], mobility, potGrad_ip[ip], fluxVal, dFlux_dP, dFlux_dS ); - for( integer ke = 0; ke < 2; ++ke ) - { - // pressure - localIndex const localDofIndexPres = k[ke] * numDof; - stack.localFluxJacobian[k[0]*numEqn + ip][localDofIndexPres] += m_dt * dhalfFlux_dP[ip][ke]; - stack.localFluxJacobian[k[1]*numEqn + ip][localDofIndexPres] -= m_dt * dhalfFlux_dP[ip][ke]; - - // saturation (hard-coded for 2-phase currently) - localIndex const localDofIndexSat = k[ke] * numDof + 1; - stack.localFluxJacobian[k[0]*numEqn + ip][localDofIndexSat] += m_dt * dhalfFlux_dS[ip][ke]; - stack.localFluxJacobian[k[1]*numEqn + ip][localDofIndexSat] -= m_dt * dhalfFlux_dS[ip][ke]; - } + } // loop over phases + } // end of else for interface conditions - // Customize the kernel with this lambda - kernelOp( k, seri, sesri, sei, connectionIndex, alpha_ip[ip], mobility, potGrad_ip[ip], fluxVal, dFlux_dP, dFlux_dS ); // Not sure what this - - } // loop over phases - } // end of else for interface conditions connectionIndex++; } } // loop over connection elements } + protected: /// Reference to the capillary pressure wrapper CAPPRESWRAPPER const m_capPressureWrapper; RELPERMWRAPPER const m_relPermWrapper; + string_array const m_interfaceFaceSetNames; + stdVector< std::array< std::tuple< constitutive::RelativePermeabilityBase *, + constitutive::CapillaryPressureBase *, + constitutive::TwoPhaseImmiscibleFluid * >, 2 > > const m_interfaceConstitutivePairs; + unordered_map< localIndex, localIndex > const m_interfaceRegionByConnector; + std::tuple< constitutive::RelativePermeabilityBase *, + constitutive::CapillaryPressureBase *, + constitutive::TwoPhaseImmiscibleFluid * > const m_interfaceConstitutivePairs_temp; + }; + /****************************************** */ /** @@ -1752,7 +2758,7 @@ class FluxComputeKernelFactory * @param[inout] localMatrix the local CRS matrix * @param[inout] localRhs the local right-hand side vector */ - template< typename POLICY, typename STENCILWRAPPER, typename CAPPRESWRAPPER, typename RELPERMWRAPPER > + template< typename POLICY, typename STENCILWRAPPER, typename CAPPRESWRAPPER, typename RELPERMWRAPPER > static void createAndLaunch( integer const numPhases, globalIndex const rankOffset, @@ -1765,6 +2771,14 @@ class FluxComputeKernelFactory STENCILWRAPPER const & stencilWrapper, CAPPRESWRAPPER const & capPresWrapper, RELPERMWRAPPER const & relPermWrapper, + string_array const & interfaceFaceSetNames, + stdVector< std::array< std::tuple< constitutive::RelativePermeabilityBase *, + constitutive::CapillaryPressureBase *, + constitutive::TwoPhaseImmiscibleFluid * >, 2 > > const & interfaceConstitutivePairs, + unordered_map< localIndex, localIndex > const & interfaceRegionByConnector, + std::tuple< constitutive::RelativePermeabilityBase *, + constitutive::CapillaryPressureBase *, + constitutive::TwoPhaseImmiscibleFluid * > const & interfaceConstitutivePairs_temp, ElementSubRegionBase const & subRegion, real64 const & dt, CRSMatrixView< real64, globalIndex const > const & localMatrix, @@ -1773,12 +2787,11 @@ class FluxComputeKernelFactory integer constexpr NUM_EQN = 2; integer constexpr NUM_DOF = 2; localIndex const domainSize = subRegion.size(); - // GEOS_UNUSED_PARAM( domainSize ); ElementRegionManager::ElementViewAccessor< arrayView1d< globalIndex const > > dofNumberAccessor = elemManager.constructArrayViewAccessor< globalIndex, 1 >( dofKey ); dofNumberAccessor.setName( solverName + "/accessors/" + dofKey ); - using kernelType = FluxComputeInterfaceConditionKernel< NUM_EQN, NUM_DOF, STENCILWRAPPER, CAPPRESWRAPPER, RELPERMWRAPPER >; + using kernelType = FluxComputeInterfaceConditionKernel< NUM_EQN, NUM_DOF, STENCILWRAPPER, CAPPRESWRAPPER, RELPERMWRAPPER >; typename kernelType::ImmiscibleMultiphaseFlowAccessors flowAccessors( elemManager, solverName ); typename kernelType::MultiphaseFluidAccessors fluidAccessors( elemManager, solverName ); typename kernelType::CapPressureAccessors capPressureAccessors( elemManager, solverName ); @@ -1787,8 +2800,8 @@ class FluxComputeKernelFactory kernelType kernel( numPhases, rankOffset, stencilWrapper, capPresWrapper, relPermWrapper, dofNumberAccessor, flowAccessors, fluidAccessors, capPressureAccessors, permAccessors, dt, localMatrix, localRhs, hasCapPressure, useTotalMassEquation, - checkPhasePresenceInGravity, domainSize); - kernelType::template launch< POLICY >( stencilWrapper.size() , kernel ); + checkPhasePresenceInGravity, interfaceFaceSetNames, interfaceConstitutivePairs, interfaceRegionByConnector, interfaceConstitutivePairs_temp, domainSize ); + kernelType::template launch< POLICY >( stencilWrapper.size(), kernel ); } }; @@ -1797,7 +2810,7 @@ class FluxComputeKernelFactory enum class KernelFlags { - TotalMassEquation = 1 << 0, // 1 + TotalMassEquation = 1 << 0, // 1 /// Add more flags like that if needed: // Flag2 = 1 << 1, // 2 @@ -2423,7 +3436,7 @@ class ResidualNormKernelFactory { ResidualNormKernel::launchLinf< POLICY >( subRegion.size(), kernel, residualNorm ); } - else // L2 norm + else // L2 norm { ResidualNormKernel::launchL2< POLICY >( subRegion.size(), kernel, residualNorm, residualNormalizer ); } @@ -2433,9 +3446,9 @@ class ResidualNormKernelFactory -} // namespace immiscible multiphasekernels +} // namespace immiscible multiphasekernels -} // namespace geos +} // namespace geos -#endif //GEOS_PHYSICSSOLVERS_FLUIDFLOW_MULTIPHASEKERNELS_HPP + #endif //GEOS_PHYSICSSOLVERS_FLUIDFLOW_MULTIPHASEKERNELS_HPP From 7927b3780d2b6191ac6917a99bd0025144e1fe40 Mon Sep 17 00:00:00 2001 From: Ammara-14 Date: Wed, 12 Nov 2025 14:02:43 -0800 Subject: [PATCH 094/102] updated --- .../JFunctionCapillaryPressure.cpp | 2 +- .../wellsTests/CMakeLists.txt | 17 - .../fluidFlow/ImmiscibleMultiphaseFlow.cpp | 2966 +++++++++-------- .../ImmiscibleMultiphaseKernels.hpp | 237 +- 4 files changed, 1690 insertions(+), 1532 deletions(-) diff --git a/src/coreComponents/constitutive/capillaryPressure/JFunctionCapillaryPressure.cpp b/src/coreComponents/constitutive/capillaryPressure/JFunctionCapillaryPressure.cpp index 738efb7b77f..5e7b9511cfa 100644 --- a/src/coreComponents/constitutive/capillaryPressure/JFunctionCapillaryPressure.cpp +++ b/src/coreComponents/constitutive/capillaryPressure/JFunctionCapillaryPressure.cpp @@ -115,7 +115,7 @@ JFunctionCapillaryPressure::JFunctionCapillaryPressure( std::string const & name toString( PermeabilityDirection::Y ) + " - only use the permeability in the y direction,\n" + toString( PermeabilityDirection::Z ) + " - only use the permeability in the z direction." ); - registerField( fields::cappres::jFuncMultiplier{}, &m_jFuncMultiplier ); + registerField< fields::cappres::jFuncMultiplier >( &m_jFuncMultiplier ); registerWrapper( viewKeyStruct::jFunctionWrappersString(), &m_jFuncKernelWrappers ). setSizedFromParent( 0 ). diff --git a/src/coreComponents/integrationTests/wellsTests/CMakeLists.txt b/src/coreComponents/integrationTests/wellsTests/CMakeLists.txt index 2a6063f14c2..5a30f2fe376 100644 --- a/src/coreComponents/integrationTests/wellsTests/CMakeLists.txt +++ b/src/coreComponents/integrationTests/wellsTests/CMakeLists.txt @@ -1,23 +1,6 @@ # Specify list of tests set( gtest_geosx_tests -<<<<<<< HEAD:src/coreComponents/unitTests/fluidFlowTests/CMakeLists.txt - testSinglePhaseMobilityKernel.cpp - testThermalCompMultiphaseFlow.cpp - testThermalSinglePhaseFlow.cpp - testFlowStatistics.cpp - testTransmissibility.cpp - testImmiscibleMultiphaseFlow.cpp - testImmiscibleInterfaceConditions.cpp ) - -if( ENABLE_PVTPackage ) - list( APPEND gtest_geosx_tests - testCompMultiphaseFlow.cpp - testCompMultiphaseFlowHybrid.cpp - testReactiveCompositionalMultiphaseOBL.cpp ) -endif() -======= testReservoirSinglePhaseMSWells.cpp ) ->>>>>>> develop:src/coreComponents/integrationTests/wellsTests/CMakeLists.txt set( tplDependencyList ${parallelDeps} gtest ) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp index 00162bb1129..d6b73163285 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp @@ -17,1394 +17,1632 @@ * @file ImmiscibleMultiphaseFlow.cpp */ -#include "ImmiscibleMultiphaseFlow.hpp" - -#include "FlowSolverBaseFields.hpp" -#include "physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlowFields.hpp" -#include "physicsSolvers/PhysicsSolverBaseKernels.hpp" -#include "physicsSolvers/fluidFlow/CompositionalMultiphaseUtilities.hpp" -#include "physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp" -#include "physicsSolvers/fluidFlow/kernels/compositional/RelativePermeabilityUpdateKernel.hpp" -#include "physicsSolvers/fluidFlow/kernels/compositional/CapillaryPressureUpdateKernel.hpp" -#include "constitutive/capillaryPressure/CapillaryPressureSelector.hpp" -#include "constitutive/relativePermeability/RelativePermeabilitySelector.hpp" - -#include "fieldSpecification/EquilibriumInitialCondition.hpp" -#include "fieldSpecification/SourceFluxBoundaryCondition.hpp" -#include "physicsSolvers/fluidFlow/SourceFluxStatistics.hpp" -#include "physicsSolvers/LogLevelsInfo.hpp" - -#include "constitutive/ConstitutivePassThru.hpp" -#include "constitutive/fluid/twophaseimmisciblefluid/TwoPhaseImmiscibleFluid.hpp" - -#include - -#if defined( __INTEL_COMPILER ) -#pragma GCC optimize "O0" -#endif - -namespace geos -{ - -using namespace dataRepository; -using namespace constitutive; -using namespace fields::immiscibleMultiphaseFlow; -using namespace immiscibleMultiphaseKernels; - - -ImmiscibleMultiphaseFlow::ImmiscibleMultiphaseFlow( const string & name, - Group * const parent ) - : - FlowSolverBase( name, parent ), - m_numPhases( 2 ), - m_hasCapPressure( false ), - m_useTotalMassEquation ( 1 ) -{ - this->registerWrapper( viewKeyStruct::inputTemperatureString(), &m_inputTemperature ). - setInputFlag( InputFlags::REQUIRED ). - setDescription( "Temperature" ); - - this->registerWrapper( viewKeyStruct::useTotalMassEquationString(), &m_useTotalMassEquation ). - setSizedFromParent( 0 ). - setInputFlag( InputFlags::OPTIONAL ). - setApplyDefaultValue( 1 ). - setDescription( "Flag indicating whether total mass equation is used" ); - - this->registerWrapper( viewKeyStruct::gravityDensitySchemeString(), &m_gravityDensityScheme ). - setSizedFromParent( 0 ). - setInputFlag( InputFlags::OPTIONAL ). - setApplyDefaultValue( GravityDensityScheme::ArithmeticAverage ). - setDescription( "Scheme for density treatment in gravity" ); - - this->registerWrapper( viewKeyStruct::solutionChangeScalingFactorString(), &m_solutionChangeScalingFactor ). - setSizedFromParent( 0 ). - setInputFlag( InputFlags::OPTIONAL ). - setApplyDefaultValue( 0.5 ). - setDescription( "Damping factor for solution change targets" ); - this->registerWrapper( viewKeyStruct::targetRelativePresChangeString(), &m_targetRelativePresChange ). - setSizedFromParent( 0 ). - setInputFlag( InputFlags::OPTIONAL ). - setApplyDefaultValue( 0.2 ). - setDescription( "Target (relative) change in pressure in a time step (expected value between 0 and 1)" ); - this->registerWrapper( viewKeyStruct::targetPhaseVolFracChangeString(), &m_targetPhaseVolFracChange ). - setSizedFromParent( 0 ). - setInputFlag( InputFlags::OPTIONAL ). - setApplyDefaultValue( 0.2 ). - setDescription( "Target (absolute) change in phase volume fraction in a time step" ); -} - -void ImmiscibleMultiphaseFlow::postInputInitialization() -{ - FlowSolverBase::postInputInitialization(); -} - -void ImmiscibleMultiphaseFlow::registerDataOnMesh( Group & meshBodies ) + #include "ImmiscibleMultiphaseFlow.hpp" + + #include "FlowSolverBaseFields.hpp" + #include "physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlowFields.hpp" + #include "physicsSolvers/PhysicsSolverBaseKernels.hpp" + #include "physicsSolvers/fluidFlow/CompositionalMultiphaseUtilities.hpp" + #include "physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp" + #include "physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/CapillaryPressureUpdateKernel.hpp" + #include "physicsSolvers/fluidFlow/kernels/compositional/ThermalAccumulationKernel.hpp" + #include "physicsSolvers/fluidFlow/kernels/compositional/RelativePermeabilityUpdateKernel.hpp" + #include "constitutive/ConstitutiveManager.hpp" + #include "constitutive/capillaryPressure/CapillaryPressureFields.hpp" + #include "constitutive/capillaryPressure/CapillaryPressureSelector.hpp" + #include "constitutive/relativePermeability/RelativePermeabilitySelector.hpp" + + #include "fieldSpecification/EquilibriumInitialCondition.hpp" + #include "fieldSpecification/SourceFluxBoundaryCondition.hpp" + #include "physicsSolvers/fluidFlow/SourceFluxStatistics.hpp" + #include "physicsSolvers/LogLevelsInfo.hpp" + + #include "constitutive/ConstitutivePassThru.hpp" + #include "constitutive/fluid/twophaseimmisciblefluid/TwoPhaseImmiscibleFluid.hpp" + + #include + + #if defined( __INTEL_COMPILER ) + #pragma GCC optimize "O0" + #endif + + namespace geos + { + + using namespace dataRepository; + using namespace constitutive; + using namespace fields::immiscibleMultiphaseFlow; + using namespace immiscibleMultiphaseKernels; + + + ImmiscibleMultiphaseFlow::ImmiscibleMultiphaseFlow( const string & name, + Group * const parent ) + : + FlowSolverBase( name, parent ), + m_numPhases( 2 ), + m_hasCapPressure( false ), + m_useTotalMassEquation ( 1 ) + { + this->registerWrapper( viewKeyStruct::inputTemperatureString(), &m_inputTemperature ). + setInputFlag( InputFlags::REQUIRED ). + setDescription( "Temperature" ); + + this->registerWrapper( viewKeyStruct::useTotalMassEquationString(), &m_useTotalMassEquation ). + setSizedFromParent( 0 ). + setInputFlag( InputFlags::OPTIONAL ). + setApplyDefaultValue( 1 ). + setDescription( "Flag indicating whether total mass equation is used" ); + + this->registerWrapper( viewKeyStruct::gravityDensitySchemeString(), &m_gravityDensityScheme ). + setSizedFromParent( 0 ). + setInputFlag( InputFlags::OPTIONAL ). + setApplyDefaultValue( GravityDensityScheme::ArithmeticAverage ). + setDescription( "Scheme for density treatment in gravity" ); + + this->registerWrapper( viewKeyStruct::solutionChangeScalingFactorString(), &m_solutionChangeScalingFactor ). + setSizedFromParent( 0 ). + setInputFlag( InputFlags::OPTIONAL ). + setApplyDefaultValue( 0.5 ). + setDescription( "Damping factor for solution change targets" ); + this->registerWrapper( viewKeyStruct::targetRelativePresChangeString(), &m_targetRelativePresChange ). + setSizedFromParent( 0 ). + setInputFlag( InputFlags::OPTIONAL ). + setApplyDefaultValue( 0.2 ). + setDescription( "Target (relative) change in pressure in a time step (expected value between 0 and 1)" ); + this->registerWrapper( viewKeyStruct::targetPhaseVolFracChangeString(), &m_targetPhaseVolFracChange ). + setSizedFromParent( 0 ). + setInputFlag( InputFlags::OPTIONAL ). + setApplyDefaultValue( 0.2 ). + setDescription( "Target (absolute) change in phase volume fraction in a time step" ); + + this->registerWrapper( viewKeyStruct::interfaceFaceSetNamesString(), + &m_interfaceFaceSetNames ). + setInputFlag( InputFlags::OPTIONAL ). + setDescription( "Names of the interface face sets" ); + } + + void ImmiscibleMultiphaseFlow::postInputInitialization() + { + FlowSolverBase::postInputInitialization(); + } + + void ImmiscibleMultiphaseFlow::registerDataOnMesh( Group & meshBodies ) + { + FlowSolverBase::registerDataOnMesh( meshBodies ); + + // 0. Find a "reference" fluid model name (at this point, models are already attached to subregions) + forDiscretizationOnMeshTargets( meshBodies, [&]( string const &, + MeshLevel & mesh, + string_array const & regionNames ) + { + mesh.getElemManager().forElementSubRegions( regionNames, + [&]( localIndex const, + ElementSubRegionBase & subRegion ) + { + // If at least one region has a capillary pressure model, consider it enabled for all + string const capPresName = getConstitutiveName< CapillaryPressureBase >( subRegion ); + if( !capPresName.empty() ) + { + m_hasCapPressure = true; + } + } ); + } ); + + m_numDofPerCell = m_numPhases; + + // 2. Register and resize all fields as necessary + forDiscretizationOnMeshTargets( meshBodies, [&]( string const &, + MeshLevel & mesh, + string_array const & regionNames ) + { + mesh.getElemManager().forElementSubRegions( regionNames, + [&]( localIndex const, + ElementSubRegionBase & subRegion ) + { + if( m_hasCapPressure ) + { + subRegion.registerWrapper< string >( viewKeyStruct::capPressureNamesString() ). + setPlotLevel( PlotLevel::NOPLOT ). + setRestartFlags( RestartFlags::NO_WRITE ). + setSizedFromParent( 0 ). + setDescription( "Name of the capillary pressure constitutive model to use" ). + reference(); + + string & capPresName = subRegion.getReference< string >( viewKeyStruct::capPressureNamesString() ); + capPresName = getConstitutiveName< CapillaryPressureBase >( subRegion ); + GEOS_THROW_IF( capPresName.empty(), + GEOS_FMT( "{}: Capillary pressure model not found on subregion {}", + getDataContext(), subRegion.getDataContext() ), + InputError ); + } + + // The resizing of the arrays needs to happen here, before the call to initializePreSubGroups, + // to make sure that the dimensions are properly set before the timeHistoryOutput starts its initialization. + subRegion.registerField< phaseVolumeFraction >( getName() ). + reference().resizeDimension< 1 >( m_numPhases ); + + subRegion.registerField< phaseVolumeFraction_n >( getName() ). + reference().resizeDimension< 1 >( m_numPhases ); + + subRegion.registerField< bcPhaseVolumeFraction >( getName() ). + reference().resizeDimension< 1 >( m_numPhases ); + + subRegion.registerField< phaseMass >( getName() ). + reference().resizeDimension< 1 >( m_numPhases ); + + subRegion.registerField< phaseMass_n >( getName() ). + reference().resizeDimension< 1 >( m_numPhases ); + + subRegion.registerField< phaseMobility >( getName() ). + reference().resizeDimension< 1 >( m_numPhases ); + + subRegion.registerField< dPhaseMobility >( getName() ). + reference().resizeDimension< 1, 2 >( m_numPhases, m_numPhases ); // dP, dS + + } ); + + } ); + } + + void ImmiscibleMultiphaseFlow::setConstitutiveNames( ElementSubRegionBase & subRegion ) const + { + setConstitutiveName< TwoPhaseImmiscibleFluid >( subRegion, viewKeyStruct::fluidNamesString(), "two phase immiscible fluid" ); + + setConstitutiveName< RelativePermeabilityBase >( subRegion, viewKeyStruct::relPermNamesString(), "relative permeability" ); + } + + void ImmiscibleMultiphaseFlow::initializePreSubGroups() + { + m_linearSolverParameters.get().mgr.strategy = LinearSolverParameters::MGR::StrategyType::immiscibleMultiphaseFVM; + + FlowSolverBase::initializePreSubGroups(); + + DomainPartition & domain = this->getGroupByPath< DomainPartition >( "/Problem/domain" ); + + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, + MeshLevel & mesh, + string_array const & regionNames ) + { + mesh.getElemManager().forElementSubRegions( regionNames, + [&]( localIndex const, + ElementSubRegionBase & subRegion ) + { + arrayView1d< real64 > const temp = subRegion.getField< fields::flow::temperature >(); + temp.setValues< parallelHostPolicy >( m_inputTemperature ); + } ); + } ); + + // ***** Create FaceElements ***** + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, + MeshLevel & meshLevel, + string_array const & regionNames ) + { + + FaceManager const & faceManager = meshLevel.getFaceManager(); + Group const & faceSetGroup = faceManager.sets(); + ElementRegionManager & elemManager = meshLevel.getElemManager(); + m_interfaceConstitutivePairs.resize( m_interfaceFaceSetNames.size() ); + + // this is the FaceElement Level + for( size_t surfaceRegionIndex=0; surfaceRegionIndex < m_interfaceFaceSetNames.size(); ++surfaceRegionIndex ) + { + string const & faceSetName = m_interfaceFaceSetNames[surfaceRegionIndex]; + SortedArrayView< localIndex const > const & faceSet = faceSetGroup.getReference< SortedArray< localIndex > >( faceSetName ); + SurfaceElementRegion & faceRegion = elemManager.getRegion< SurfaceElementRegion >( faceSetName ); + + for( localIndex const faceIndex : faceSet ) + { + localIndex const faceIndices[2] = { faceIndex, faceIndex }; + faceRegion.addToSurfaceMesh( &faceManager, faceIndices ); + } + + FaceElementSubRegion const & faceSubRegion = faceRegion.getUniqueSubRegion< FaceElementSubRegion >(); + FixedToManyElementRelation const & faceElementsToCells = faceSubRegion.getToCellRelation(); + + std::function< std::tuple< CellElementSubRegion *, CellElementSubRegion * >(localIndex) > getSubregions = [&]( localIndex surfaceSubRegionIndex ) -> std::tuple< CellElementSubRegion *, + CellElementSubRegion * > + { + + int regionIdx0 = faceElementsToCells.m_toElementRegion[surfaceSubRegionIndex][0]; + int regionIdx1 = faceElementsToCells.m_toElementRegion[surfaceSubRegionIndex][1]; + int subRegionIdx0 = faceElementsToCells.m_toElementSubRegion[surfaceSubRegionIndex][0]; + int subRegionIdx1 = faceElementsToCells.m_toElementSubRegion[surfaceSubRegionIndex][1]; + + CellElementRegion & region0 = elemManager.getRegion< CellElementRegion >( regionIdx0 ); + CellElementRegion & region1 = elemManager.getRegion< CellElementRegion >( regionIdx1 ); + + CellElementSubRegion * subRegion0 = ®ion0.getSubRegion< CellElementSubRegion >( subRegionIdx0 ); + CellElementSubRegion * subRegion1 = ®ion1.getSubRegion< CellElementSubRegion >( subRegionIdx1 ); + return std::make_tuple( subRegion0, subRegion1 ); + }; + + // std::tuple< CellElementSubRegion *, CellElementSubRegion * > subRegionPair = getSubregions( surfaceRegionIndex ); + // CellElementSubRegion * subRegion0 = std::get< 0 >( subRegionPair ); + // CellElementSubRegion * subRegion1 = std::get< 1 >( subRegionPair ); + + // // get constitutives by type and name: relPerms, capPressures, Fluids (three pointers) + // std::string & relPermName0 = subRegion0->getReference< std::string >( viewKeyStruct::relPermNamesString()); + // std::string & relPermName1 = subRegion1->getReference< std::string >( viewKeyStruct::relPermNamesString()); + // RelativePermeabilityBase * relPerm0 = &getConstitutiveModel< RelativePermeabilityBase >( *subRegion0, relPermName0 ); + // RelativePermeabilityBase * relPerm1 = &getConstitutiveModel< RelativePermeabilityBase >( *subRegion1, relPermName1 ); + + // std::string & cappresName0 = subRegion0->getReference< std::string >( viewKeyStruct::capPressureNamesString()); + // std::string & cappresName1 = subRegion1->getReference< std::string >( viewKeyStruct::capPressureNamesString()); + // CapillaryPressureBase * capPressure0 = &getConstitutiveModel< CapillaryPressureBase >( *subRegion0, cappresName0 ); + // CapillaryPressureBase * capPressure1 = &getConstitutiveModel< CapillaryPressureBase >( *subRegion1, cappresName1 ); + + // std::string & fluidName0 = subRegion0->getReference< std::string >( viewKeyStruct::fluidNamesString() ); + // std::string & fluidName1 = subRegion1->getReference< std::string >( viewKeyStruct::fluidNamesString() ); + + // TwoPhaseImmiscibleFluid * fluid0 = &getConstitutiveModel< TwoPhaseImmiscibleFluid >( *subRegion0, fluidName0 ); + // TwoPhaseImmiscibleFluid * fluid1 = &getConstitutiveModel< TwoPhaseImmiscibleFluid >( *subRegion1, fluidName1 ); + + // m_interfaceConstitutivePairs[surfaceRegionIndex][0] = std::make_tuple( relPerm0, capPressure0, fluid0 ); + // m_interfaceConstitutivePairs[surfaceRegionIndex][1] = std::make_tuple( relPerm1, capPressure1, fluid1 ); + // Find a representative face element in this surface region with two adjacent cells +localIndex fei = -1; + +// Prefer face element 0 if valid; otherwise scan +if( faceElementsToCells.size() > 0 ) { - FlowSolverBase::registerDataOnMesh( meshBodies ); - - // 0. Find a "reference" fluid model name (at this point, models are already attached to subregions) - forDiscretizationOnMeshTargets( meshBodies, [&]( string const &, - MeshLevel & mesh, - string_array const & regionNames ) + // Check if face element 0 has two adjacent cells + if( faceElementsToCells.m_toElementRegion[0].size() >= 2 ) { - mesh.getElemManager().forElementSubRegions( regionNames, - [&]( localIndex const, - ElementSubRegionBase & subRegion ) - { - // If at least one region has a capillary pressure model, consider it enabled for all - string const capPresName = getConstitutiveName< CapillaryPressureBase >( subRegion ); - if( !capPresName.empty() ) - { - m_hasCapPressure = true; - } - } ); - } ); - - m_numDofPerCell = m_numPhases; - - // 2. Register and resize all fields as necessary - forDiscretizationOnMeshTargets( meshBodies, [&]( string const &, - MeshLevel & mesh, - string_array const & regionNames ) + fei = 0; + } + else { - mesh.getElemManager().forElementSubRegions( regionNames, - [&]( localIndex const, - ElementSubRegionBase & subRegion ) + // Scan to find the first interior face element with two neighbors + for( localIndex i = 1; i < faceElementsToCells.size(); ++i ) { - if( m_hasCapPressure ) + if( faceElementsToCells.m_toElementRegion[i].size() >= 2 ) { - subRegion.registerWrapper< string >( viewKeyStruct::capPressureNamesString() ). - setPlotLevel( PlotLevel::NOPLOT ). - setRestartFlags( RestartFlags::NO_WRITE ). - setSizedFromParent( 0 ). - setDescription( "Name of the capillary pressure constitutive model to use" ). - reference(); - - string & capPresName = subRegion.getReference< string >( viewKeyStruct::capPressureNamesString() ); - capPresName = getConstitutiveName< CapillaryPressureBase >( subRegion ); - GEOS_THROW_IF( capPresName.empty(), - GEOS_FMT( "{}: Capillary pressure model not found on subregion {}", - getDataContext(), subRegion.getDataContext() ), - InputError ); + fei = i; + break; } - - // The resizing of the arrays needs to happen here, before the call to initializePreSubGroups, - // to make sure that the dimensions are properly set before the timeHistoryOutput starts its initialization. - subRegion.registerField< phaseVolumeFraction >( getName() ). - reference().resizeDimension< 1 >( m_numPhases ); - - subRegion.registerField< phaseVolumeFraction_n >( getName() ). - reference().resizeDimension< 1 >( m_numPhases ); - - subRegion.registerField< bcPhaseVolumeFraction >( getName() ). - reference().resizeDimension< 1 >( m_numPhases ); - - subRegion.registerField< phaseMass >( getName() ). - reference().resizeDimension< 1 >( m_numPhases ); - - subRegion.registerField< phaseMass_n >( getName() ). - reference().resizeDimension< 1 >( m_numPhases ); - - subRegion.registerField< phaseMobility >( getName() ). - reference().resizeDimension< 1 >( m_numPhases ); - - subRegion.registerField< dPhaseMobility >( getName() ). - reference().resizeDimension< 1, 2 >( m_numPhases, m_numPhases ); // dP, dS - - } ); - - } ); -} - -void ImmiscibleMultiphaseFlow::setConstitutiveNames( ElementSubRegionBase & subRegion ) const -{ - setConstitutiveName< TwoPhaseImmiscibleFluid >( subRegion, viewKeyStruct::fluidNamesString(), "two phase immiscible fluid" ); - - setConstitutiveName< RelativePermeabilityBase >( subRegion, viewKeyStruct::relPermNamesString(), "relative permeability" ); -} - -void ImmiscibleMultiphaseFlow::initializePreSubGroups() -{ - m_linearSolverParameters.get().mgr.strategy = LinearSolverParameters::MGR::StrategyType::immiscibleMultiphaseFVM; - - FlowSolverBase::initializePreSubGroups(); - - DomainPartition & domain = this->getGroupByPath< DomainPartition >( "/Problem/domain" ); - - forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, - MeshLevel & mesh, - string_array const & regionNames ) - { - mesh.getElemManager().forElementSubRegions( regionNames, - [&]( localIndex const, - ElementSubRegionBase & subRegion ) - { - arrayView1d< real64 > const temp = subRegion.getField< fields::flow::temperature >(); - temp.setValues< parallelHostPolicy >( m_inputTemperature ); - } ); - } ); -} - - -void ImmiscibleMultiphaseFlow::updateFluidModel( ObjectManagerBase & dataGroup ) const -{ - GEOS_MARK_FUNCTION; - - arrayView1d< real64 const > const pres = dataGroup.getField< fields::flow::pressure >(); - - TwoPhaseImmiscibleFluid & fluid = getConstitutiveModel< TwoPhaseImmiscibleFluid >( dataGroup, dataGroup.getReference< string >( viewKeyStruct::fluidNamesString() ) ); - - constitutiveUpdatePassThru( fluid, [&] ( auto & castedFluid ) - { - using FluidType = TYPEOFREF( castedFluid ); - typename FluidType::KernelWrapper fluidWrapper = castedFluid.createKernelWrapper(); - - FluidUpdateKernel::launch< parallelDevicePolicy<> >( dataGroup.size(), fluidWrapper, pres ); - } ); -} - - -void ImmiscibleMultiphaseFlow::updateRelPermModel( ObjectManagerBase & dataGroup ) const -{ - GEOS_MARK_FUNCTION; - - - GEOS_UNUSED_VAR( dataGroup ); - - arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFrac = - dataGroup.getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); - - string const & relPermName = dataGroup.getReference< string >( viewKeyStruct::relPermNamesString() ); - RelativePermeabilityBase & relPerm = getConstitutiveModel< RelativePermeabilityBase >( dataGroup, relPermName ); - - constitutive::constitutiveUpdatePassThru( relPerm, [&] ( auto & castedRelPerm ) - { - typename TYPEOFREF( castedRelPerm ) ::KernelWrapper relPermWrapper = castedRelPerm.createKernelWrapper(); - - isothermalCompositionalMultiphaseBaseKernels:: - RelativePermeabilityUpdateKernel:: - launch< parallelDevicePolicy<> >( dataGroup.size(), - relPermWrapper, - phaseVolFrac ); - } ); -} - -void ImmiscibleMultiphaseFlow::updateCapPressureModel( ObjectManagerBase & dataGroup ) const -{ - GEOS_MARK_FUNCTION; - - if( m_hasCapPressure ) - { - arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFrac = - dataGroup.getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); - - string const & cappresName = dataGroup.getReference< string >( viewKeyStruct::capPressureNamesString() ); - CapillaryPressureBase & capPressure = getConstitutiveModel< CapillaryPressureBase >( dataGroup, cappresName ); - - constitutive::constitutiveUpdatePassThru( capPressure, [&] ( auto & castedCapPres ) - { - typename TYPEOFREF( castedCapPres ) ::KernelWrapper capPresWrapper = castedCapPres.createKernelWrapper(); - - isothermalCompositionalMultiphaseBaseKernels:: - CapillaryPressureUpdateKernel:: - launch< parallelDevicePolicy<> >( dataGroup.size(), - capPresWrapper, - phaseVolFrac ); - } ); - } -} - - -void ImmiscibleMultiphaseFlow::updateFluidState( ElementSubRegionBase & subRegion ) const -{ - GEOS_MARK_FUNCTION; - - updateFluidModel( subRegion ); - updateVolumeConstraint( subRegion ); - updatePhaseMass( subRegion ); - updateRelPermModel( subRegion ); - updatePhaseMobility( subRegion ); - updateCapPressureModel( subRegion ); -} - - -void ImmiscibleMultiphaseFlow::updatePhaseMass( ElementSubRegionBase & subRegion ) const -{ - GEOS_MARK_FUNCTION; - - string const & solidName = subRegion.getReference< string >( viewKeyStruct::solidNamesString() ); - string const & fluidName = subRegion.getReference< string >( viewKeyStruct::fluidNamesString() ); - - TwoPhaseImmiscibleFluid const & fluid = getConstitutiveModel< TwoPhaseImmiscibleFluid >( subRegion, fluidName ); - CoupledSolidBase const & solid = getConstitutiveModel< CoupledSolidBase >( subRegion, solidName ); - - arrayView1d< real64 const > const volume = subRegion.getElementVolume(); - arrayView2d< real64 const > const porosity = solid.getPorosity(); - - arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFrac= subRegion.getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); - arrayView3d< real64 const, multifluid::USD_PHASE > phaseDens = fluid.phaseDensity(); - arrayView2d< real64, immiscibleFlow::USD_PHASE > const phaseMass = subRegion.getField< fields::immiscibleMultiphaseFlow::phaseMass >(); - - // Might be needed for geomechanics????? if so, need to change the accumulation as well? - //arrayView1d< real64 > const deltaVolume = subRegion.getField< fields::flow::deltaVolume >(); - - forAll< parallelDevicePolicy<> >( subRegion.size(), [=] GEOS_HOST_DEVICE ( localIndex const ei ) - { - real64 const poreVolume = volume[ei] * porosity[ei][0]; - for( integer ip = 0; ip < 2; ++ip ) - { - phaseMass[ei][ip] = poreVolume * phaseVolFrac[ei][ip] * phaseDens[ei][0][ip]; - } - } ); -} - - -void ImmiscibleMultiphaseFlow::updatePhaseMobility( ObjectManagerBase & dataGroup ) const -{ - GEOS_MARK_FUNCTION; - - // note that the phase mobility computed here also includes phase density - string const & fluidName = dataGroup.getReference< string >( viewKeyStruct::fluidNamesString() ); - TwoPhaseImmiscibleFluid const & fluid = getConstitutiveModel< TwoPhaseImmiscibleFluid >( dataGroup, fluidName ); - - string const & relpermName = dataGroup.getReference< string >( viewKeyStruct::relPermNamesString() ); - RelativePermeabilityBase const & relperm = getConstitutiveModel< RelativePermeabilityBase >( dataGroup, relpermName ); - - immiscibleMultiphaseKernels:: - PhaseMobilityKernelFactory:: - createAndLaunch< parallelDevicePolicy<> >( m_numPhases, - dataGroup, - fluid, - relperm ); -} - -void ImmiscibleMultiphaseFlow::initializeFluidState( MeshLevel & mesh, - string_array const & regionNames ) -{ - GEOS_MARK_FUNCTION; - - mesh.getElemManager().forElementSubRegions( regionNames, - [&]( localIndex const, - ElementSubRegionBase & subRegion ) - { - // 2. Assume global component fractions have been prescribed. - // Initialize constitutive state to get fluid density. - updateFluidModel( subRegion ); - - } ); - - // for some reason CUDA does not want the host_device lambda to be defined inside the generic lambda - // I need the exact type of the subRegion for updateSolidflowProperties to work well. - mesh.getElemManager().forElementSubRegions< CellElementSubRegion, - SurfaceElementSubRegion >( regionNames, [&]( localIndex const, - auto & subRegion ) - { - // 4. Initialize/update dependent state quantities - - // 4.1 Update the constitutive models that only depend on - // - the primary variables - // - the fluid constitutive quantities (as they have already been updated) - // We postpone the other constitutive models for now - // In addition, to avoid multiplying permeability/porosity bay netToGross in the assembly kernel, we do it once and for all here - arrayView1d< real64 const > const netToGross = subRegion.template getField< fields::flow::netToGross >(); - CoupledSolidBase const & porousSolid = - getConstitutiveModel< CoupledSolidBase >( subRegion, subRegion.template getReference< string >( viewKeyStruct::solidNamesString() ) ); - PermeabilityBase const & permeabilityModel = - getConstitutiveModel< PermeabilityBase >( subRegion, subRegion.template getReference< string >( viewKeyStruct::permeabilityNamesString() ) ); - permeabilityModel.scaleHorizontalPermeability( netToGross ); - porousSolid.scaleReferencePorosity( netToGross ); - saveConvergedState( subRegion ); // necessary for a meaningful porosity update in sequential schemes - updatePorosityAndPermeability( subRegion ); - - // Now, we initialize and update each constitutive model one by one - - // 4.2 Save the computed porosity into the old porosity - // - // Note: - // - This must be called after updatePorosityAndPermeability - // - This step depends on porosity - string const & solidName = subRegion.template getReference< string >( viewKeyStruct::solidNamesString() ); - CoupledSolidBase const & porousMaterial = getConstitutiveModel< CoupledSolidBase >( subRegion, solidName ); - porousMaterial.initializeState(); - - // 4.3 Initialize/update the relative permeability model using the initial phase volume fraction - // This is needed to handle relative permeability hysteresis - // Also, initialize the fluid model - // - // Note: - // - This must be called after updateVolumeConstraint - // - This step depends on phaseVolFraction - - // initialized phase volume fraction - arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFrac = - subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); - - string const & relpermName = subRegion.template getReference< string >( viewKeyStruct::relPermNamesString() ); - RelativePermeabilityBase & relPermMaterial = - getConstitutiveModel< RelativePermeabilityBase >( subRegion, relpermName ); - relPermMaterial.saveConvergedPhaseVolFractionState( phaseVolFrac ); // this needs to happen before calling updateRelPermModel - updateRelPermModel( subRegion ); - relPermMaterial.saveConvergedState(); // this needs to happen after calling updateRelPermModel - - // 4.4 Then, we initialize/update the capillary pressure model - // - // Note: - // - This must be called after updatePorosityAndPermeability - // - This step depends on porosity and permeability - if( m_hasCapPressure ) - { - // initialized porosity - arrayView2d< real64 const > const porosity = porousMaterial.getPorosity(); - - string const & permName = subRegion.template getReference< string >( viewKeyStruct::permeabilityNamesString() ); - PermeabilityBase const & permeabilityMaterial = getConstitutiveModel< PermeabilityBase >( subRegion, permName ); - // initialized permeability - arrayView3d< real64 const > const permeability = permeabilityMaterial.permeability(); - - string const & capPressureName = subRegion.template getReference< string >( viewKeyStruct::capPressureNamesString() ); - CapillaryPressureBase const & capPressureMaterial = - getConstitutiveModel< CapillaryPressureBase >( subRegion, capPressureName ); - capPressureMaterial.initializeRockState( porosity, permeability ); // this needs to happen before calling updateCapPressureModel - updateCapPressureModel( subRegion ); } - - // 4.5 Update the phase mobility - // - // Note: - // - This must be called after updateRelPermModel - // - This step depends phaseRelPerm - updatePhaseMobility( subRegion ); - - } ); - - // 5. Save initial pressure - mesh.getElemManager().forElementSubRegions( regionNames, [&]( localIndex const, - ElementSubRegionBase & subRegion ) - { - arrayView1d< real64 const > const pres = subRegion.getField< fields::flow::pressure >(); - arrayView1d< real64 > const initPres = subRegion.getField< fields::flow::initialPressure >(); - arrayView1d< real64 const > const temp = subRegion.getField< fields::flow::temperature >(); - arrayView1d< real64 > const initTemp = subRegion.template getField< fields::flow::initialTemperature >(); - initPres.setValues< parallelDevicePolicy<> >( pres ); - initTemp.setValues< parallelDevicePolicy<> >( temp ); - - // TODO: Missing updatePhaseMass? - } ); -} - - -void ImmiscibleMultiphaseFlow::initializePostInitialConditionsPreSubGroups() -{ - GEOS_MARK_FUNCTION; - - FlowSolverBase::initializePostInitialConditionsPreSubGroups(); - - DomainPartition & domain = this->getGroupByPath< DomainPartition >( "/Problem/domain" ); - - forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, - MeshLevel & mesh, - string_array const & regionNames ) - { - FieldIdentifiers fieldsToBeSync; - fieldsToBeSync.addElementFields( { fields::flow::pressure::key(), - fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key() }, - regionNames ); - - CommunicationTools::getInstance().synchronizeFields( fieldsToBeSync, mesh, domain.getNeighbors(), false ); - } ); - - initializeState( domain ); -} - - -void -ImmiscibleMultiphaseFlow::implicitStepSetup( real64 const & GEOS_UNUSED_PARAM( time_n ), - real64 const & GEOS_UNUSED_PARAM( dt ), - DomainPartition & domain ) -{ - forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, - MeshLevel & mesh, - string_array const & regionNames ) - { - mesh.getElemManager().forElementSubRegions< CellElementSubRegion, - SurfaceElementSubRegion >( regionNames, - [&]( localIndex const, - auto & subRegion ) - { - saveConvergedState( subRegion ); - - // update porosity, permeability - updatePorosityAndPermeability( subRegion ); - // update all fluid properties - updateVolumeConstraint( subRegion ); - updateFluidState( subRegion ); - - // after the update, save the new saturation - arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFrac = - subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); - - arrayView2d< real64, immiscibleFlow::USD_PHASE > const phaseVolFrac_n = - subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction_n >(); - phaseVolFrac_n.setValues< parallelDevicePolicy<> >( phaseVolFrac ); - - arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const & phaseMass = - subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseMass >(); - - arrayView2d< real64, immiscibleFlow::USD_PHASE > const & phaseMass_n = - subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseMass_n >(); - phaseMass_n.setValues< parallelDevicePolicy<> >( phaseMass ); - - } ); - } ); + } } -void ImmiscibleMultiphaseFlow::assembleSystem( real64 const GEOS_UNUSED_PARAM( time_n ), - real64 const dt, - DomainPartition & domain, - DofManager const & dofManager, - CRSMatrixView< real64, globalIndex const > const & localMatrix, - arrayView1d< real64 > const & localRhs ) +// If no valid face element, skip this surface region +if( fei < 0 ) { - GEOS_MARK_FUNCTION; - - assembleAccumulationTerm( domain, - dofManager, - localMatrix, - localRhs ); - - - assembleFluxTerms( dt, - domain, - dofManager, - localMatrix, - localRhs ); + continue; } - - -void ImmiscibleMultiphaseFlow::assembleAccumulationTerm( DomainPartition & domain, +std::tuple< CellElementSubRegion *, CellElementSubRegion * > subRegionPair = getSubregions( fei ); +CellElementSubRegion * subRegion0 = std::get< 0 >( subRegionPair ); +CellElementSubRegion * subRegion1 = std::get< 1 >( subRegionPair ); + +// get constitutives by type and name: relPerms, capPressures, Fluids (three pointers) +std::string & relPermName0 = subRegion0->getReference< std::string >( viewKeyStruct::relPermNamesString()); +std::string & relPermName1 = subRegion1->getReference< std::string >( viewKeyStruct::relPermNamesString()); +RelativePermeabilityBase * relPerm0 = &getConstitutiveModel< RelativePermeabilityBase >( *subRegion0, relPermName0 ); +RelativePermeabilityBase * relPerm1 = &getConstitutiveModel< RelativePermeabilityBase >( *subRegion1, relPermName1 ); + +std::string & cappresName0 = subRegion0->getReference< std::string >( viewKeyStruct::capPressureNamesString()); +std::string & cappresName1 = subRegion1->getReference< std::string >( viewKeyStruct::capPressureNamesString()); +CapillaryPressureBase * capPressure0 = &getConstitutiveModel< CapillaryPressureBase >( *subRegion0, cappresName0 ); +CapillaryPressureBase * capPressure1 = &getConstitutiveModel< CapillaryPressureBase >( *subRegion1, cappresName1 ); + +std::string & fluidName0 = subRegion0->getReference< std::string >( viewKeyStruct::fluidNamesString() ); +std::string & fluidName1 = subRegion1->getReference< std::string >( viewKeyStruct::fluidNamesString() ); + +TwoPhaseImmiscibleFluid * fluid0 = &getConstitutiveModel< TwoPhaseImmiscibleFluid >( *subRegion0, fluidName0 ); +TwoPhaseImmiscibleFluid * fluid1 = &getConstitutiveModel< TwoPhaseImmiscibleFluid >( *subRegion1, fluidName1 ); + +m_interfaceConstitutivePairs[surfaceRegionIndex][0] = std::make_tuple( relPerm0, capPressure0, fluid0 ); +m_interfaceConstitutivePairs[surfaceRegionIndex][1] = std::make_tuple( relPerm1, capPressure1, fluid1 ); + + } + } ); + + } + + + void ImmiscibleMultiphaseFlow::updateFluidModel( ObjectManagerBase & dataGroup ) const + { + GEOS_MARK_FUNCTION; + + arrayView1d< real64 const > const pres = dataGroup.getField< fields::flow::pressure >(); + + TwoPhaseImmiscibleFluid & fluid = getConstitutiveModel< TwoPhaseImmiscibleFluid >( dataGroup, dataGroup.getReference< string >( viewKeyStruct::fluidNamesString() ) ); + + constitutiveUpdatePassThru( fluid, [&] ( auto & castedFluid ) + { + using FluidType = TYPEOFREF( castedFluid ); + typename FluidType::KernelWrapper fluidWrapper = castedFluid.createKernelWrapper(); + + FluidUpdateKernel::launch< parallelDevicePolicy<> >( dataGroup.size(), fluidWrapper, pres ); + } ); + } + + + void ImmiscibleMultiphaseFlow::updateRelPermModel( ObjectManagerBase & dataGroup ) const + { + GEOS_MARK_FUNCTION; + + + GEOS_UNUSED_VAR( dataGroup ); + + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFrac = + dataGroup.getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); + + string const & relPermName = dataGroup.getReference< string >( viewKeyStruct::relPermNamesString() ); + RelativePermeabilityBase & relPerm = getConstitutiveModel< RelativePermeabilityBase >( dataGroup, relPermName ); + + constitutive::constitutiveUpdatePassThru( relPerm, [&] ( auto & castedRelPerm ) + { + typename TYPEOFREF( castedRelPerm ) ::KernelWrapper relPermWrapper = castedRelPerm.createKernelWrapper(); + + isothermalCompositionalMultiphaseBaseKernels:: + RelativePermeabilityUpdateKernel:: + launch< parallelDevicePolicy<> >( dataGroup.size(), + relPermWrapper, + phaseVolFrac ); + } ); + } + + void ImmiscibleMultiphaseFlow::updateCapPressureModel( ObjectManagerBase & dataGroup ) const + { + GEOS_MARK_FUNCTION; + + if( m_hasCapPressure ) + { + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFrac = + dataGroup.getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); + + string const & cappresName = dataGroup.getReference< string >( viewKeyStruct::capPressureNamesString() ); + CapillaryPressureBase & capPressure = getConstitutiveModel< CapillaryPressureBase >( dataGroup, cappresName ); + + constitutive::constitutiveUpdatePassThru( capPressure, [&] ( auto & castedCapPres ) + { + typename TYPEOFREF( castedCapPres ) ::KernelWrapper capPresWrapper = castedCapPres.createKernelWrapper(); + + // isothermalCompositionalMultiphaseBaseKernels:: + immiscibleMultiphaseKernels:: + CapillaryPressureUpdateKernel:: + launch< parallelDevicePolicy<> >( dataGroup.size(), + capPresWrapper, + phaseVolFrac ); + } ); + } + } + + + void ImmiscibleMultiphaseFlow::updateFluidState( ElementSubRegionBase & subRegion ) const + { + GEOS_MARK_FUNCTION; + + updateFluidModel( subRegion ); + updateVolumeConstraint( subRegion ); + updatePhaseMass( subRegion ); + updateRelPermModel( subRegion ); + updatePhaseMobility( subRegion ); + updateCapPressureModel( subRegion ); + } + + + void ImmiscibleMultiphaseFlow::updatePhaseMass( ElementSubRegionBase & subRegion ) const + { + GEOS_MARK_FUNCTION; + + string const & solidName = subRegion.getReference< string >( viewKeyStruct::solidNamesString() ); + string const & fluidName = subRegion.getReference< string >( viewKeyStruct::fluidNamesString() ); + + TwoPhaseImmiscibleFluid const & fluid = getConstitutiveModel< TwoPhaseImmiscibleFluid >( subRegion, fluidName ); + CoupledSolidBase const & solid = getConstitutiveModel< CoupledSolidBase >( subRegion, solidName ); + + arrayView1d< real64 const > const volume = subRegion.getElementVolume(); + arrayView2d< real64 const > const porosity = solid.getPorosity(); + + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFrac= subRegion.getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); + arrayView3d< real64 const, multifluid::USD_PHASE > phaseDens = fluid.phaseDensity(); + arrayView2d< real64, immiscibleFlow::USD_PHASE > const phaseMass = subRegion.getField< fields::immiscibleMultiphaseFlow::phaseMass >(); + + // Might be needed for geomechanics????? if so, need to change the accumulation as well? + //arrayView1d< real64 > const deltaVolume = subRegion.getField< fields::flow::deltaVolume >(); + + forAll< parallelDevicePolicy<> >( subRegion.size(), [=] GEOS_HOST_DEVICE ( localIndex const ei ) + { + real64 const poreVolume = volume[ei] * porosity[ei][0]; + for( integer ip = 0; ip < 2; ++ip ) + { + phaseMass[ei][ip] = poreVolume * phaseVolFrac[ei][ip] * phaseDens[ei][0][ip]; + } + } ); + } + + + void ImmiscibleMultiphaseFlow::updatePhaseMobility( ObjectManagerBase & dataGroup ) const + { + GEOS_MARK_FUNCTION; + + // note that the phase mobility computed here also includes phase density + string const & fluidName = dataGroup.getReference< string >( viewKeyStruct::fluidNamesString() ); + TwoPhaseImmiscibleFluid const & fluid = getConstitutiveModel< TwoPhaseImmiscibleFluid >( dataGroup, fluidName ); + + string const & relpermName = dataGroup.getReference< string >( viewKeyStruct::relPermNamesString() ); + RelativePermeabilityBase const & relperm = getConstitutiveModel< RelativePermeabilityBase >( dataGroup, relpermName ); + + immiscibleMultiphaseKernels:: + PhaseMobilityKernelFactory:: + createAndLaunch< parallelDevicePolicy<> >( m_numPhases, + dataGroup, + fluid, + relperm ); + } + + void ImmiscibleMultiphaseFlow::initializeFluidState( MeshLevel & mesh, + string_array const & regionNames ) + { + GEOS_MARK_FUNCTION; + + mesh.getElemManager().forElementSubRegions( regionNames, + [&]( localIndex const, + ElementSubRegionBase & subRegion ) + { + // 2. Assume global component fractions have been prescribed. + // Initialize constitutive state to get fluid density. + updateFluidModel( subRegion ); + + } ); + + // for some reason CUDA does not want the host_device lambda to be defined inside the generic lambda + // I need the exact type of the subRegion for updateSolidflowProperties to work well. + mesh.getElemManager().forElementSubRegions< CellElementSubRegion, + SurfaceElementSubRegion >( regionNames, [&]( localIndex const, + auto & subRegion ) + { + // 4. Initialize/update dependent state quantities + + // 4.1 Update the constitutive models that only depend on + // - the primary variables + // - the fluid constitutive quantities (as they have already been updated) + // We postpone the other constitutive models for now + // In addition, to avoid multiplying permeability/porosity bay netToGross in the assembly kernel, we do it once and for all here + arrayView1d< real64 const > const netToGross = subRegion.template getField< fields::flow::netToGross >(); + CoupledSolidBase const & porousSolid = + getConstitutiveModel< CoupledSolidBase >( subRegion, subRegion.template getReference< string >( viewKeyStruct::solidNamesString() ) ); + PermeabilityBase const & permeabilityModel = + getConstitutiveModel< PermeabilityBase >( subRegion, subRegion.template getReference< string >( viewKeyStruct::permeabilityNamesString() ) ); + permeabilityModel.scaleHorizontalPermeability( netToGross ); + porousSolid.scaleReferencePorosity( netToGross ); + saveConvergedState( subRegion ); // necessary for a meaningful porosity update in sequential schemes + updatePorosityAndPermeability( subRegion ); + + // Now, we initialize and update each constitutive model one by one + + // 4.2 Save the computed porosity into the old porosity + // + // Note: + // - This must be called after updatePorosityAndPermeability + // - This step depends on porosity + string const & solidName = subRegion.template getReference< string >( viewKeyStruct::solidNamesString() ); + CoupledSolidBase const & porousMaterial = getConstitutiveModel< CoupledSolidBase >( subRegion, solidName ); + porousMaterial.initializeState(); + + // 4.3 Initialize/update the relative permeability model using the initial phase volume fraction + // This is needed to handle relative permeability hysteresis + // Also, initialize the fluid model + // + // Note: + // - This must be called after updateVolumeConstraint + // - This step depends on phaseVolFraction + + // initialized phase volume fraction + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFrac = + subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); + + string const & relpermName = subRegion.template getReference< string >( viewKeyStruct::relPermNamesString() ); + RelativePermeabilityBase & relPermMaterial = + getConstitutiveModel< RelativePermeabilityBase >( subRegion, relpermName ); + relPermMaterial.saveConvergedPhaseVolFractionState( phaseVolFrac ); // this needs to happen before calling updateRelPermModel + updateRelPermModel( subRegion ); + relPermMaterial.saveConvergedState(); // this needs to happen after calling updateRelPermModel + + // 4.4 Then, we initialize/update the capillary pressure model + // + // Note: + // - This must be called after updatePorosityAndPermeability + // - This step depends on porosity and permeability + if( m_hasCapPressure ) + { + // initialized porosity + arrayView2d< real64 const > const porosity = porousMaterial.getPorosity(); + + string const & permName = subRegion.template getReference< string >( viewKeyStruct::permeabilityNamesString() ); + PermeabilityBase const & permeabilityMaterial = getConstitutiveModel< PermeabilityBase >( subRegion, permName ); + // initialized permeability + arrayView3d< real64 const > const permeability = permeabilityMaterial.permeability(); + + string const & capPressureName = subRegion.template getReference< string >( viewKeyStruct::capPressureNamesString() ); + CapillaryPressureBase const & capPressureMaterial = + getConstitutiveModel< CapillaryPressureBase >( subRegion, capPressureName ); + capPressureMaterial.initializeRockState( porosity, permeability ); // this needs to happen before calling updateCapPressureModel + updateCapPressureModel( subRegion ); + } + + // 4.5 Update the phase mobility + // + // Note: + // - This must be called after updateRelPermModel + // - This step depends phaseRelPerm + updatePhaseMobility( subRegion ); + + } ); + + // 5. Save initial pressure + mesh.getElemManager().forElementSubRegions( regionNames, [&]( localIndex const, + ElementSubRegionBase & subRegion ) + { + arrayView1d< real64 const > const pres = subRegion.getField< fields::flow::pressure >(); + arrayView1d< real64 > const initPres = subRegion.getField< fields::flow::initialPressure >(); + arrayView1d< real64 const > const temp = subRegion.getField< fields::flow::temperature >(); + arrayView1d< real64 > const initTemp = subRegion.template getField< fields::flow::initialTemperature >(); + initPres.setValues< parallelDevicePolicy<> >( pres ); + initTemp.setValues< parallelDevicePolicy<> >( temp ); + + // TODO: Missing updatePhaseMass? + } ); + } + + + void ImmiscibleMultiphaseFlow::initializePostInitialConditionsPreSubGroups() + { + GEOS_MARK_FUNCTION; + + FlowSolverBase::initializePostInitialConditionsPreSubGroups(); + + DomainPartition & domain = this->getGroupByPath< DomainPartition >( "/Problem/domain" ); + + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, + MeshLevel & mesh, + string_array const & regionNames ) + { + FieldIdentifiers fieldsToBeSync; + fieldsToBeSync.addElementFields( { fields::flow::pressure::key(), + fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key() }, + regionNames ); + + CommunicationTools::getInstance().synchronizeFields( fieldsToBeSync, mesh, domain.getNeighbors(), false ); + } ); + + // Retrieve the numerical methods and finite volume manager + FiniteVolumeManager const & fvManager = domain.getNumericalMethodManager().getFiniteVolumeManager(); + FluxApproximationBase const & fluxApprox = fvManager.getFluxApproximation( m_discretizationName ); + const geos::string flux_approximation_name = fluxApprox.getName(); + + // Clear the existing mapping between connector indices and interface region indices + m_interfaceRegionByConnector.clear(); + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( std::string const &, + MeshLevel & meshLevel, + string_array const & regionNames ) + { + // Access the face manager and retrieve the face set group for the current mesh level + FaceManager const & faceManager = meshLevel.getFaceManager(); + Group const & faceSetGroup = faceManager.sets(); + + // Access the connector indices map (face index → connector index) + Group & stencilGroup = + meshLevel.getGroup( FluxApproximationBase::groupKeyStruct::stencilMeshGroupString()) + .getGroup( flux_approximation_name ); + CellElementStencilTPFA & stencil = + stencilGroup.getReference< CellElementStencilTPFA >( + FluxApproximationBase::viewKeyStruct::cellStencilString()); + unordered_map< localIndex, localIndex > const & connectorIndices = stencil.getConnectorIndices(); + + // for all interface face sets to map connector indices to their corresponding interface region indices + for( size_t surfaceRegionIndex = 0; surfaceRegionIndex < m_interfaceFaceSetNames.size(); ++surfaceRegionIndex ) + { + // Iterate over each face and associate its connector index + std::string const & faceSetName = m_interfaceFaceSetNames[surfaceRegionIndex]; + for( localIndex kf : faceSetGroup.getReference< SortedArray< localIndex > >( faceSetName )) + { + auto it = connectorIndices.find( kf ); + if( it != connectorIndices.end()) + { + // Map the connector index to the corresponding surface region index + m_interfaceRegionByConnector[it->second] = surfaceRegionIndex; + } + } + } + } ); + + + initializeState( domain ); + } + + + void + ImmiscibleMultiphaseFlow::implicitStepSetup( real64 const & GEOS_UNUSED_PARAM( time_n ), + real64 const & GEOS_UNUSED_PARAM( dt ), + DomainPartition & domain ) + { + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, + MeshLevel & mesh, + string_array const & regionNames ) + { + mesh.getElemManager().forElementSubRegions< CellElementSubRegion, + SurfaceElementSubRegion >( regionNames, + [&]( localIndex const, + auto & subRegion ) + { + saveConvergedState( subRegion ); + + // update porosity, permeability + updatePorosityAndPermeability( subRegion ); + // update all fluid properties + updateVolumeConstraint( subRegion ); + updateFluidState( subRegion ); + + // after the update, save the new saturation + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFrac = + subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); + + arrayView2d< real64, immiscibleFlow::USD_PHASE > const phaseVolFrac_n = + subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction_n >(); + phaseVolFrac_n.setValues< parallelDevicePolicy<> >( phaseVolFrac ); + + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const & phaseMass = + subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseMass >(); + + arrayView2d< real64, immiscibleFlow::USD_PHASE > const & phaseMass_n = + subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseMass_n >(); + phaseMass_n.setValues< parallelDevicePolicy<> >( phaseMass ); + + } ); + } ); + } + + void ImmiscibleMultiphaseFlow::assembleSystem( real64 const GEOS_UNUSED_PARAM( time_n ), + real64 const dt, + DomainPartition & domain, + DofManager const & dofManager, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) + { + GEOS_MARK_FUNCTION; + + assembleAccumulationTerm( domain, + dofManager, + localMatrix, + localRhs ); + + + assembleFluxTerms( dt, + domain, + dofManager, + localMatrix, + localRhs ); + } + + + + void ImmiscibleMultiphaseFlow::assembleAccumulationTerm( DomainPartition & domain, + DofManager const & dofManager, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) const + { + GEOS_MARK_FUNCTION; + + + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, + MeshLevel const & mesh, + string_array const & regionNames ) + { + mesh.getElemManager().forElementSubRegions( regionNames, + [&]( localIndex const, + ElementSubRegionBase const & subRegion ) + { + string const dofKey = dofManager.getKey( viewKeyStruct::elemDofFieldString() ); + string const & solidName = subRegion.getReference< string >( viewKeyStruct::solidNamesString() ); + string const & fluidName = subRegion.getReference< string >( viewKeyStruct::fluidNamesString() ); + + TwoPhaseImmiscibleFluid const & fluid = getConstitutiveModel< TwoPhaseImmiscibleFluid >( subRegion, fluidName ); + CoupledSolidBase const & solid = getConstitutiveModel< CoupledSolidBase >( subRegion, solidName ); + + immiscibleMultiphaseKernels:: + AccumulationKernelFactory:: + createAndLaunch< parallelDevicePolicy<> >( m_numPhases, + dofManager.rankOffset(), + m_useTotalMassEquation, + dofKey, + subRegion, + fluid, + solid, + localMatrix, + localRhs ); + + } ); + } ); + } + + void ImmiscibleMultiphaseFlow::assembleFluxTerms( real64 const dt, + DomainPartition & domain, + DofManager const & dofManager, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) const + { + GEOS_MARK_FUNCTION; + + NumericalMethodsManager const & numericalMethodManager = domain.getNumericalMethodManager(); + FiniteVolumeManager const & fvManager = numericalMethodManager.getFiniteVolumeManager(); + FluxApproximationBase const & fluxApprox = fvManager.getFluxApproximation( m_discretizationName ); + + string const & dofKey = dofManager.getKey( viewKeyStruct::elemDofFieldString() ); + + + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&] ( string const &, + MeshLevel & mesh, + string_array const & regionNames ) + { + if( m_hasCapPressure ) + { + mesh.getElemManager().forElementSubRegions( regionNames, + [&]( localIndex const, + ElementSubRegionBase & subRegion ) // Check if you need this. + { + // // Capillary pressure wrapper + // string const & cappresName = subRegion.getReference< string >( viewKeyStruct::capPressureNamesString() ); + // BrooksCoreyCapillaryPressure & capPressure = getConstitutiveModel< BrooksCoreyCapillaryPressure >( subRegion, cappresName ); + // CapillaryPressureBase * capPressure1 = &getConstitutiveModel< CapillaryPressureBase >( subRegion, cappresName ); + // BrooksCoreyCapillaryPressure::KernelWrapper capPresWrapper = capPressure.createKernelWrapper(); + + // // Relative permeability wrapper + // string const & relPermName = subRegion.getReference< string >( viewKeyStruct::relPermNamesString() ); + // BrooksCoreyRelativePermeability & relPerm = getConstitutiveModel< BrooksCoreyRelativePermeability >( subRegion, relPermName ); + // RelativePermeabilityBase * relPerm1 = &getConstitutiveModel< RelativePermeabilityBase >( subRegion, relPermName ); + // BrooksCoreyRelativePermeability::KernelWrapper relPermWrapper = relPerm.createKernelWrapper(); + + // // fluid + // string const & fluidName = subRegion.getReference< string >( viewKeyStruct::fluidNamesString() ); + // TwoPhaseImmiscibleFluid * fluid = &getConstitutiveModel< TwoPhaseImmiscibleFluid >( subRegion, fluidName ); + + // // m_interfaceConstitutivePairs[0][0] = std::make_tuple( relPerm1, capPressure1, fluid ); + // // m_interfaceConstitutivePairs[0][1] = std::make_tuple( relPerm1, capPressure1, fluid ); + + // auto interfaceConstitutivePairs_temp = std::make_tuple( relPerm1, capPressure1, fluid ); + + fluxApprox.forAllStencils( mesh, [&]( auto & stencil ) + { + typename TYPEOFREF( stencil ) ::KernelWrapper stencilWrapper = stencil.createKernelWrapper(); + immiscibleMultiphaseKernels:: + FluxComputeKernelFactory::createAndLaunch< parallelDevicePolicy<> >( m_numPhases, + dofManager.rankOffset(), + dofKey, + m_hasCapPressure, + m_useTotalMassEquation, + m_gravityDensityScheme == GravityDensityScheme::PhasePresence, + getName(), + mesh.getElemManager(), + stencilWrapper, + // capPresWrapper, + // relPermWrapper, + m_interfaceFaceSetNames, + m_interfaceConstitutivePairs, + m_interfaceRegionByConnector, + // interfaceConstitutivePairs_temp, + subRegion, + dt, + localMatrix.toViewConstSizes(), + localRhs.toView() ); + } ); + } ); + } + else + { + fluxApprox.forAllStencils( mesh, [&]( auto & stencil ) + { + typename TYPEOFREF( stencil ) ::KernelWrapper stencilWrapper = stencil.createKernelWrapper(); + immiscibleMultiphaseKernels:: + FluxComputeKernelFactory::createAndLaunch< parallelDevicePolicy<> >( m_numPhases, + dofManager.rankOffset(), + dofKey, + m_hasCapPressure, + m_useTotalMassEquation, + m_gravityDensityScheme == GravityDensityScheme::PhasePresence, + getName(), + mesh.getElemManager(), + stencilWrapper, + dt, + localMatrix.toViewConstSizes(), + localRhs.toView() ); + } ); + } + + } ); + } + + // Ryan: Looks like this will need to be overwritten as well... + // I have left the CompositionalMultiphaseFVM implementation for reference + void ImmiscibleMultiphaseFlow::setupDofs( DomainPartition const & domain, + DofManager & dofManager ) const + { + GEOS_UNUSED_VAR( domain, dofManager ); + // add a field for the cell-centered degrees of freedom + dofManager.addField( viewKeyStruct::elemDofFieldString(), + FieldLocation::Elem, + m_numDofPerCell, + getMeshTargets() ); + + //// this call with instruct GEOS to reorder the dof numbers + //dofManager.setLocalReorderingType( viewKeyStruct::elemDofFieldString(), + // DofManager::LocalReorderingType::ReverseCutHillMcKee ); + + NumericalMethodsManager const & numericalMethodManager = domain.getNumericalMethodManager(); + FiniteVolumeManager const & fvManager = numericalMethodManager.getFiniteVolumeManager(); + FluxApproximationBase const & fluxApprox = fvManager.getFluxApproximation( m_discretizationName ); + dofManager.addCoupling( viewKeyStruct::elemDofFieldString(), fluxApprox ); + } + + void ImmiscibleMultiphaseFlow::applyBoundaryConditions( real64 const time_n, + real64 const dt, + DomainPartition & domain, DofManager const & dofManager, CRSMatrixView< real64, globalIndex const > const & localMatrix, - arrayView1d< real64 > const & localRhs ) const -{ - GEOS_MARK_FUNCTION; - - - forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, - MeshLevel const & mesh, - string_array const & regionNames ) - { - mesh.getElemManager().forElementSubRegions( regionNames, - [&]( localIndex const, - ElementSubRegionBase const & subRegion ) - { - string const dofKey = dofManager.getKey( viewKeyStruct::elemDofFieldString() ); - string const & solidName = subRegion.getReference< string >( viewKeyStruct::solidNamesString() ); - string const & fluidName = subRegion.getReference< string >( viewKeyStruct::fluidNamesString() ); - - TwoPhaseImmiscibleFluid const & fluid = getConstitutiveModel< TwoPhaseImmiscibleFluid >( subRegion, fluidName ); - CoupledSolidBase const & solid = getConstitutiveModel< CoupledSolidBase >( subRegion, solidName ); - - immiscibleMultiphaseKernels:: - AccumulationKernelFactory:: - createAndLaunch< parallelDevicePolicy<> >( m_numPhases, - dofManager.rankOffset(), - m_useTotalMassEquation, - dofKey, - subRegion, - fluid, - solid, - localMatrix, - localRhs ); - - } ); - } ); -} - -void ImmiscibleMultiphaseFlow::assembleFluxTerms( real64 const dt, - DomainPartition const & domain, - DofManager const & dofManager, - CRSMatrixView< real64, globalIndex const > const & localMatrix, - arrayView1d< real64 > const & localRhs ) const -{ - GEOS_MARK_FUNCTION; - - NumericalMethodsManager const & numericalMethodManager = domain.getNumericalMethodManager(); - FiniteVolumeManager const & fvManager = numericalMethodManager.getFiniteVolumeManager(); - FluxApproximationBase const & fluxApprox = fvManager.getFluxApproximation( m_discretizationName ); - - string const & dofKey = dofManager.getKey( viewKeyStruct::elemDofFieldString() ); - - forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&] ( string const &, - MeshLevel const & mesh, + arrayView1d< real64 > const & localRhs ) + { + GEOS_MARK_FUNCTION; + + // apply pressure boundary conditions. + applyDirichletBC( time_n, dt, dofManager, domain, localMatrix.toViewConstSizes(), localRhs.toView() ); + + // apply flux boundary conditions + applySourceFluxBC( time_n, dt, dofManager, domain, localMatrix.toViewConstSizes(), localRhs.toView() ); + } + + + namespace + { + char const bcLogMessage[] = + "ImmiscibleMultiphaseFlow {}: at time {}s, " + "the <{}> boundary condition '{}' is applied to the element set '{}' in subRegion '{}'. " + "\nThe scale of this boundary condition is {} and multiplies the value of the provided function (if any). " + "\nThe total number of target elements (including ghost elements) is {}. " + "\nNote that if this number is equal to zero for all subRegions, the boundary condition will not be applied on this element set."; + } + + bool ImmiscibleMultiphaseFlow::validateDirichletBC( DomainPartition & domain, + real64 const time ) const + { + constexpr integer MAX_NP = 2; + FieldSpecificationManager & fsManager = FieldSpecificationManager::getInstance(); + + bool bcConsistent = true; + + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, + MeshLevel & mesh, string_array const & ) - { - fluxApprox.forAllStencils( mesh, [&]( auto & stencil ) - { - typename TYPEOFREF( stencil ) ::KernelWrapper stencilWrapper = stencil.createKernelWrapper(); - immiscibleMultiphaseKernels:: - FluxComputeKernelFactory::createAndLaunch< parallelDevicePolicy<> >( m_numPhases, - dofManager.rankOffset(), - dofKey, - m_hasCapPressure, - m_useTotalMassEquation, - m_gravityDensityScheme == GravityDensityScheme::PhasePresence, - getName(), - mesh.getElemManager(), - stencilWrapper, - dt, - localMatrix.toViewConstSizes(), - localRhs.toView() ); - } ); - } ); -} - -void ImmiscibleMultiphaseFlow::setupDofs( DomainPartition const & domain, - DofManager & dofManager ) const -{ - GEOS_UNUSED_VAR( domain, dofManager ); - // add a field for the cell-centered degrees of freedom - dofManager.addField( viewKeyStruct::elemDofFieldString(), - FieldLocation::Elem, - m_numDofPerCell, - getMeshTargets() ); - - //// this call with instruct GEOS to reorder the dof numbers - //dofManager.setLocalReorderingType( viewKeyStruct::elemDofFieldString(), - // DofManager::LocalReorderingType::ReverseCutHillMcKee ); - - NumericalMethodsManager const & numericalMethodManager = domain.getNumericalMethodManager(); - FiniteVolumeManager const & fvManager = numericalMethodManager.getFiniteVolumeManager(); - FluxApproximationBase const & fluxApprox = fvManager.getFluxApproximation( m_discretizationName ); - dofManager.addCoupling( viewKeyStruct::elemDofFieldString(), fluxApprox ); -} - -void ImmiscibleMultiphaseFlow::applyBoundaryConditions( real64 const time_n, - real64 const dt, - DomainPartition & domain, - DofManager const & dofManager, - CRSMatrixView< real64, globalIndex const > const & localMatrix, - arrayView1d< real64 > const & localRhs ) -{ - GEOS_MARK_FUNCTION; - - // apply pressure boundary conditions. - applyDirichletBC( time_n, dt, dofManager, domain, localMatrix.toViewConstSizes(), localRhs.toView() ); - - // apply flux boundary conditions - applySourceFluxBC( time_n, dt, dofManager, domain, localMatrix.toViewConstSizes(), localRhs.toView() ); -} - - -namespace -{ -char const bcLogMessage[] = - "ImmiscibleMultiphaseFlow {}: at time {}s, " - "the <{}> boundary condition '{}' is applied to the element set '{}' in subRegion '{}'. " - "\nThe scale of this boundary condition is {} and multiplies the value of the provided function (if any). " - "\nThe total number of target elements (including ghost elements) is {}. " - "\nNote that if this number is equal to zero for all subRegions, the boundary condition will not be applied on this element set."; -} - -bool ImmiscibleMultiphaseFlow::validateDirichletBC( DomainPartition & domain, - real64 const time ) const -{ - constexpr integer MAX_NP = 2; - FieldSpecificationManager & fsManager = FieldSpecificationManager::getInstance(); - - bool bcConsistent = true; - - forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, - MeshLevel & mesh, - string_array const & ) - { - // map: regionName -> subRegionName -> setName -> numPhases to check pressure/phase are present consistent - map< string, map< string, map< string, ComponentMask< MAX_NP > > > > bcPresCompStatusMap; - - // 1. Check pressure Dirichlet BCs - fsManager.apply< ElementSubRegionBase >( time, - mesh, - fields::flow::pressure::key(), - [&]( FieldSpecificationBase const &, - string const & setName, - SortedArrayView< localIndex const > const &, - ElementSubRegionBase & subRegion, - string const & ) - { - // Check whether pressure has already been applied to this set - string const & subRegionName = subRegion.getName(); - string const & regionName = subRegion.getParent().getParent().getName(); - - auto & subRegionSetMap = bcPresCompStatusMap[regionName][subRegionName]; - if( subRegionSetMap.count( setName ) > 0 ) - { - bcConsistent = false; - GEOS_WARNING( BCMessage::pressureConflict( regionName, subRegionName, setName, - fields::flow::pressure::key() ) ); - } - subRegionSetMap[setName].setNumComp( m_numPhases ); - } ); - // 2. Check saturation Dirichlet BCs - fsManager.apply< ElementSubRegionBase >( time, - mesh, - fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key(), - [&] ( FieldSpecificationBase const & fs, + { + // map: regionName -> subRegionName -> setName -> numPhases to check pressure/phase are present consistent + map< string, map< string, map< string, ComponentMask< MAX_NP > > > > bcPresCompStatusMap; + + // 1. Check pressure Dirichlet BCs + fsManager.apply< ElementSubRegionBase >( time, + mesh, + fields::flow::pressure::key(), + [&]( FieldSpecificationBase const &, string const & setName, SortedArrayView< localIndex const > const &, ElementSubRegionBase & subRegion, string const & ) - { - string const & subRegionName = subRegion.getName( ); - string const & regionName = subRegion.getParent().getParent().getName(); - integer const comp = fs.getComponent(); - - auto & subRegionSetMap = bcPresCompStatusMap[regionName][subRegionName]; - if( subRegionSetMap.count( setName ) == 0 ) - { - bcConsistent = false; - GEOS_WARNING( BCMessage::missingPressure( regionName, subRegionName, setName, - fields::flow::pressure::key() ) ); - } - if( comp < 0 || comp >= m_numPhases ) - { - bcConsistent = false; - GEOS_WARNING( BCMessage::invalidComponentIndex( comp, fs.getName(), - fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key() ) ); - return; // can't check next part with invalid component id - } - - ComponentMask< MAX_NP > & compMask = subRegionSetMap[setName]; - if( compMask[comp] ) - { - bcConsistent = false; - fsManager.forSubGroups< EquilibriumInitialCondition >( [&] ( EquilibriumInitialCondition const & bc ) - { - string_array const & componentNames = bc.getComponentNames(); - GEOS_WARNING( BCMessage::conflictingComposition( comp, componentNames[comp], - regionName, subRegionName, setName, - fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key() ) ); - } ); - } - compMask.set( comp ); - } ); - - // 3.2 Check consistency between composition BC applied to sets - // Note: for a temperature-only boundary condition, this loop does not do anything - for( auto const & regionEntry : bcPresCompStatusMap ) - { - for( auto const & subRegionEntry : regionEntry.second ) - { - for( auto const & setEntry : subRegionEntry.second ) - { - ComponentMask< MAX_NP > const & compMask = setEntry.second; - - fsManager.forSubGroups< EquilibriumInitialCondition >( [&] ( EquilibriumInitialCondition const & fs ) - { - string_array const & componentNames = fs.getComponentNames(); - for( size_t ic = 0; ic < componentNames.size(); ic++ ) - { - if( !compMask[ic] ) - { - bcConsistent = false; - GEOS_WARNING( BCMessage::notAppliedOnRegion( ic, componentNames[ic], - regionEntry.first, subRegionEntry.first, setEntry.first, - fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key() ) ); - } - } - } ); - } - } - } - } ); - - return bcConsistent; -} - -void ImmiscibleMultiphaseFlow::applyDirichletBC( real64 const time_n, - real64 const dt, - DofManager const & dofManager, - DomainPartition & domain, - CRSMatrixView< real64, globalIndex const > const & localMatrix, - arrayView1d< real64 > const & localRhs ) const -{ - GEOS_MARK_FUNCTION; - - // Only validate BC at the beginning of Newton loop - if( m_nonlinearSolverParameters.m_numNewtonIterations == 0 ) - { - bool const bcConsistent = validateDirichletBC( domain, time_n + dt ); - GEOS_ERROR_IF( !bcConsistent, GEOS_FMT( "ImmiscibleMultiphaseFlow {}: inconsistent boundary conditions", getDataContext() ) ); - } - - FieldSpecificationManager & fsManager = FieldSpecificationManager::getInstance(); - - forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, - MeshLevel & mesh, - string_array const & ) - { - - // 1. Apply pressure Dirichlet BCs, store in a separate field - applyFieldValue< ElementSubRegionBase >( time_n, dt, mesh, bcLogMessage, - fields::flow::pressure::key(), fields::flow::bcPressure::key() ); - // 2. Apply saturation BC (phase volume fraction) and store in a separate field - applyFieldValue< ElementSubRegionBase >( time_n, dt, mesh, bcLogMessage, - fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key(), - fields::immiscibleMultiphaseFlow::bcPhaseVolumeFraction::key() ); - - globalIndex const rankOffset = dofManager.rankOffset(); - string const dofKey = dofManager.getKey( viewKeyStruct::elemDofFieldString() ); - - // 3. Call constitutive update - fsManager.apply< ElementSubRegionBase >( time_n + dt, - mesh, - fields::flow::pressure::key(), - [&] ( FieldSpecificationBase const &, - string const &, - SortedArrayView< localIndex const > const & targetSet, - ElementSubRegionBase & subRegion, - string const & ) - { - - arrayView1d< real64 const > const bcPres = - subRegion.getReference< array1d< real64 > >( fields::flow::bcPressure::key() ); - arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const bcPhaseVolFraction = - subRegion.getReference< array2d< real64, immiscibleFlow::LAYOUT_PHASE > >( - fields::immiscibleMultiphaseFlow::bcPhaseVolumeFraction::key() ); - - arrayView1d< integer const > const ghostRank = - subRegion.getReference< array1d< integer > >( ObjectManagerBase::viewKeyStruct::ghostRankString() ); - arrayView1d< globalIndex const > const dofNumber = - subRegion.getReference< array1d< globalIndex > >( dofKey ); - arrayView1d< real64 const > const pres = - subRegion.getReference< array1d< real64 > >( fields::flow::pressure::key() ); - arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFraction = - subRegion.getReference< array2d< real64, immiscibleFlow::LAYOUT_PHASE > >( - fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key() ); - - integer const numPhase = m_numPhases; - - - forAll< parallelDevicePolicy<> >( targetSet.size(), [=] GEOS_HOST_DEVICE ( localIndex const a ) - { - localIndex const ei = targetSet[a]; - if( ghostRank[ei] >= 0 ) - { - return; - } - - globalIndex const dofIndex = dofNumber[ei]; - localIndex const localRow = dofIndex - rankOffset; - real64 rhsValue; - - // 3.1. Apply pressure value to the matrix/rhs - FieldSpecificationEqual::SpecifyFieldValue( dofIndex, - rankOffset, - localMatrix, - rhsValue, - bcPres[ei], - pres[ei] ); - localRhs[localRow] = rhsValue; - - // 3.2. For each phase, apply target saturation value - for( integer ip = 0; ip < numPhase-1; ++ip ) - { - FieldSpecificationEqual::SpecifyFieldValue( dofIndex + ip + 1, - rankOffset, - localMatrix, - rhsValue, - bcPhaseVolFraction[ei][ip], - phaseVolFraction[ei][ip] ); - localRhs[localRow + ip + 1] = rhsValue; - } - } ); - } ); - } ); -} - -void ImmiscibleMultiphaseFlow::applySourceFluxBC( real64 const time, + { + // Check whether pressure has already been applied to this set + string const & subRegionName = subRegion.getName(); + string const & regionName = subRegion.getParent().getParent().getName(); + + auto & subRegionSetMap = bcPresCompStatusMap[regionName][subRegionName]; + if( subRegionSetMap.count( setName ) > 0 ) + { + bcConsistent = false; + GEOS_WARNING( BCMessage::pressureConflict( regionName, subRegionName, setName, + fields::flow::pressure::key() ) ); + } + subRegionSetMap[setName].setNumComp( m_numPhases ); + } ); + // 2. Check saturation Dirichlet BCs + fsManager.apply< ElementSubRegionBase >( time, + mesh, + fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key(), + [&] ( FieldSpecificationBase const & fs, + string const & setName, + SortedArrayView< localIndex const > const &, + ElementSubRegionBase & subRegion, + string const & ) + { + string const & subRegionName = subRegion.getName( ); + string const & regionName = subRegion.getParent().getParent().getName(); + integer const comp = fs.getComponent(); + + auto & subRegionSetMap = bcPresCompStatusMap[regionName][subRegionName]; + if( subRegionSetMap.count( setName ) == 0 ) + { + bcConsistent = false; + GEOS_WARNING( BCMessage::missingPressure( regionName, subRegionName, setName, + fields::flow::pressure::key() ) ); + } + if( comp < 0 || comp >= m_numPhases ) + { + bcConsistent = false; + GEOS_WARNING( BCMessage::invalidComponentIndex( comp, fs.getName(), + fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key() ) ); + return; // can't check next part with invalid component id + } + + ComponentMask< MAX_NP > & compMask = subRegionSetMap[setName]; + if( compMask[comp] ) + { + bcConsistent = false; + fsManager.forSubGroups< EquilibriumInitialCondition >( [&] ( EquilibriumInitialCondition const & bc ) + { + string_array const & componentNames = bc.getComponentNames(); + GEOS_WARNING( BCMessage::conflictingComposition( comp, componentNames[comp], + regionName, subRegionName, setName, + fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key() ) ); + } ); + } + compMask.set( comp ); + } ); + + // 3.2 Check consistency between composition BC applied to sets + // Note: for a temperature-only boundary condition, this loop does not do anything + for( auto const & regionEntry : bcPresCompStatusMap ) + { + for( auto const & subRegionEntry : regionEntry.second ) + { + for( auto const & setEntry : subRegionEntry.second ) + { + ComponentMask< MAX_NP > const & compMask = setEntry.second; + + fsManager.forSubGroups< EquilibriumInitialCondition >( [&] ( EquilibriumInitialCondition const & fs ) + { + string_array const & componentNames = fs.getComponentNames(); + for( size_t ic = 0; ic < componentNames.size(); ic++ ) + { + if( !compMask[ic] ) + { + bcConsistent = false; + GEOS_WARNING( BCMessage::notAppliedOnRegion( ic, componentNames[ic], + regionEntry.first, subRegionEntry.first, setEntry.first, + fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key() ) ); + } + } + } ); + } + } + } + } ); + + return bcConsistent; + } + + void ImmiscibleMultiphaseFlow::applyDirichletBC( real64 const time_n, real64 const dt, DofManager const & dofManager, DomainPartition & domain, CRSMatrixView< real64, globalIndex const > const & localMatrix, arrayView1d< real64 > const & localRhs ) const -{ - GEOS_MARK_FUNCTION; - - FieldSpecificationManager & fsManager = FieldSpecificationManager::getInstance(); - - string const dofKey = dofManager.getKey( viewKeyStruct::elemDofFieldString() ); - - // Step 1: count individual source flux boundary conditions - - std::map< string, localIndex > bcNameToBcId; - localIndex bcCounter = 0; - - fsManager.forSubGroups< SourceFluxBoundaryCondition >( [&] ( SourceFluxBoundaryCondition const & bc ) - { - // collect all the bc names to idx - bcNameToBcId[bc.getName()] = bcCounter; - bcCounter++; - } ); - - if( bcCounter == 0 ) - { - return; - } - - // Step 2: count the set size for each source flux (each source flux may have multiple target sets) - - array1d< globalIndex > bcAllSetsSize( bcNameToBcId.size() ); - - computeSourceFluxSizeScalingFactor( time, - dt, - domain, - bcNameToBcId, - bcAllSetsSize.toView() ); - - // Step 3: we are ready to impose the boundary condition, normalized by the set size - - forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, - MeshLevel & mesh, - string_array const & ) - { - - fsManager.apply< ElementSubRegionBase, - SourceFluxBoundaryCondition >( time + dt, - mesh, - SourceFluxBoundaryCondition::catalogName(), - [&]( SourceFluxBoundaryCondition const & fs, - string const & setName, - SortedArrayView< localIndex const > const & targetSet, - ElementSubRegionBase & subRegion, - string const & ) - { - if( fs.getLogLevel() >= 1 && m_nonlinearSolverParameters.m_numNewtonIterations == 0 ) - { - globalIndex const numTargetElems = MpiWrapper::sum< globalIndex >( targetSet.size() ); - GEOS_LOG_RANK_0( GEOS_FMT( bcLogMessage, - getName(), time+dt, fs.getCatalogName(), fs.getName(), - setName, subRegion.getName(), fs.getScale(), numTargetElems ) ); - } - - if( targetSet.size() == 0 ) - { - return; - } - if( !subRegion.hasWrapper( dofKey ) ) - { - if( fs.getLogLevel() >= 1 ) - { - GEOS_LOG_RANK( GEOS_FMT( "{}: trying to apply SourceFlux, but its targetSet named '{}' intersects with non-simulated region named '{}'.", - getDataContext(), setName, subRegion.getName() ) ); - } - return; - } - - arrayView1d< globalIndex const > const dofNumber = subRegion.getReference< array1d< globalIndex > >( dofKey ); - arrayView1d< integer const > const ghostRank = subRegion.ghostRank(); - - // Step 3.1: get the values of the source boundary condition that need to be added to the rhs - - array1d< globalIndex > dofArray( targetSet.size() ); - array1d< real64 > rhsContributionArray( targetSet.size() ); - arrayView1d< real64 > rhsContributionArrayView = rhsContributionArray.toView(); - localIndex const rankOffset = dofManager.rankOffset(); - - RAJA::ReduceSum< parallelDeviceReduce, real64 > massProd( 0.0 ); - - // note that the dofArray will not be used after this step (simpler to use dofNumber instead) - fs.computeRhsContribution< FieldSpecificationAdd, - parallelDevicePolicy<> >( targetSet.toViewConst(), - time + dt, - dt, - subRegion, - dofNumber, - rankOffset, - localMatrix, - dofArray.toView(), - rhsContributionArrayView, - [] GEOS_HOST_DEVICE ( localIndex const ) - { - return 0.0; - } ); - - // Step 3.2: we are ready to add the right-hand side contributions, taking into account our equation layout - - // get the normalizer - real64 const sizeScalingFactor = bcAllSetsSize[bcNameToBcId.at( fs.getName())]; - integer const fluidPhaseId = fs.getComponent(); - integer const numFluidPhases = m_numPhases; - integer useTotalMassEquation = m_useTotalMassEquation; - forAll< parallelDevicePolicy<> >( targetSet.size(), [sizeScalingFactor, - targetSet, - rankOffset, - ghostRank, - fluidPhaseId, - numFluidPhases, - useTotalMassEquation, - dofNumber, - rhsContributionArrayView, - localRhs, - massProd] GEOS_HOST_DEVICE ( localIndex const a ) - { - // we need to filter out ghosts here, because targetSet may contain them - localIndex const ei = targetSet[a]; - if( ghostRank[ei] >= 0 ) - { - return; - } - - real64 const rhsValue = rhsContributionArrayView[a] / sizeScalingFactor; // scale the contribution by the sizeScalingFactor here! - massProd += rhsValue; - if( useTotalMassEquation > 0 ) - { - // for all "fluid components", we add the value to the total mass balance equation - globalIndex const totalMassBalanceRow = dofNumber[ei] - rankOffset; - localRhs[totalMassBalanceRow] += rhsValue; - if( fluidPhaseId < numFluidPhases - 1 ) - { - globalIndex const compMassBalanceRow = totalMassBalanceRow + fluidPhaseId + 1; // component mass bal equations are shifted - localRhs[compMassBalanceRow] += rhsValue; - } - } - else - { - globalIndex const compMassBalanceRow = dofNumber[ei] - rankOffset + fluidPhaseId; - localRhs[compMassBalanceRow] += rhsValue; - } - } ); - - SourceFluxStatsAggregator::forAllFluxStatWrappers( subRegion, fs.getName(), - [&]( SourceFluxStatsAggregator::WrappedStats & wrapper ) - { - // set the new sub-region statistics for this timestep - array1d< real64 > massProdArr{ m_numPhases }; - massProdArr[fluidPhaseId] = massProd.get(); - wrapper.gatherTimeStepStats( time, dt, massProdArr.toViewConst(), targetSet.size() ); - } ); - } ); - } ); -} - -real64 ImmiscibleMultiphaseFlow::calculateResidualNorm( real64 const & GEOS_UNUSED_PARAM( time_n ), - real64 const & GEOS_UNUSED_PARAM( dt ), - DomainPartition const & domain, - DofManager const & dofManager, - arrayView1d< real64 const > const & localRhs ) -{ - GEOS_MARK_FUNCTION; - array1d< real64 > localResidualNorm; - array1d< real64 > localResidualNormalizer; - localResidualNorm.resize( numNorm ); - localResidualNormalizer.resize( numNorm ); - - physicsSolverBaseKernels::NormType const normType = getNonlinearSolverParameters().normType(); - - globalIndex const rankOffset = dofManager.rankOffset(); - string const dofKey = dofManager.getKey( viewKeyStruct::elemDofFieldString() ); - - forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, - MeshLevel const & mesh, - string_array const & regionNames ) - { - mesh.getElemManager().forElementSubRegions( regionNames, - [&]( localIndex const, - ElementSubRegionBase const & subRegion ) - { - real64 subRegionResidualNorm[numNorm]{}; - real64 subRegionResidualNormalizer[numNorm]{}; - - string const & solidName = subRegion.getReference< string >( viewKeyStruct::solidNamesString() ); - CoupledSolidBase const & solid = getConstitutiveModel< CoupledSolidBase >( subRegion, solidName ); - - // step 1: compute the norm in the subRegion - - real64 subRegionFlowResidualNorm[1]{}; - real64 subRegionFlowResidualNormalizer[1]{}; - - immiscibleMultiphaseKernels:: - ResidualNormKernelFactory::createAndLaunch< parallelDevicePolicy<> >( normType, - 2, - rankOffset, - dofKey, - localRhs, - subRegion, - solid, - m_nonlinearSolverParameters.m_minNormalizer, - subRegionFlowResidualNorm, - subRegionFlowResidualNormalizer ); - subRegionResidualNorm[0] = subRegionFlowResidualNorm[0]; - subRegionResidualNormalizer[0] = subRegionFlowResidualNormalizer[0]; - - // step 2: first reduction across meshBodies/regions/subRegions - if( normType == physicsSolverBaseKernels::NormType::Linf ) - { - physicsSolverBaseKernels::LinfResidualNormHelper:: - updateLocalNorm< numNorm >( subRegionResidualNorm, localResidualNorm ); - } - else - { - physicsSolverBaseKernels::L2ResidualNormHelper:: - updateLocalNorm< numNorm >( subRegionResidualNorm, subRegionResidualNormalizer, localResidualNorm, localResidualNormalizer ); - } - } ); - } ); - - real64 residualNorm = 0.0; - residualNorm = localResidualNorm[0]; - if( normType == physicsSolverBaseKernels::NormType::Linf ) - { - physicsSolverBaseKernels::LinfResidualNormHelper::computeGlobalNorm( localResidualNorm[0], residualNorm ); - } - else - { - physicsSolverBaseKernels::L2ResidualNormHelper::computeGlobalNorm( localResidualNorm[0], localResidualNormalizer[0], residualNorm ); - } - - GEOS_LOG_LEVEL_RANK_0_NLR( logInfo::ResidualNorm, GEOS_FMT( " ( R{} ) = ( {:4.2e} )", - coupledSolverAttributePrefix(), residualNorm )) - - getConvergenceStats().setResidualValue( GEOS_FMT( "R{}", coupledSolverAttributePrefix()), residualNorm ); - - return residualNorm; -} - -void ImmiscibleMultiphaseFlow::applySystemSolution( DofManager const & dofManager, - arrayView1d< real64 const > const & localSolution, - real64 const scalingFactor, - real64 const dt, - DomainPartition & domain ) -{ - GEOS_UNUSED_VAR( dt ); - - DofManager::CompMask pressureMask( m_numDofPerCell, 0, 1 ); - - // 1. apply the pressure update - dofManager.addVectorToField( localSolution, - viewKeyStruct::elemDofFieldString(), - fields::flow::pressure::key(), - scalingFactor, - pressureMask ); - - // 2. apply the phaseVolumeFraction update - dofManager.addVectorToField( localSolution, - viewKeyStruct::elemDofFieldString(), - fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key(), - scalingFactor, - ~pressureMask ); - - // 3. synchronize - forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&] ( string const &, + { + GEOS_MARK_FUNCTION; + + // Only validate BC at the beginning of Newton loop + if( m_nonlinearSolverParameters.m_numNewtonIterations == 0 ) + { + bool const bcConsistent = validateDirichletBC( domain, time_n + dt ); + GEOS_ERROR_IF( !bcConsistent, GEOS_FMT( "ImmiscibleMultiphaseFlow {}: inconsistent boundary conditions", getDataContext() ) ); + } + + FieldSpecificationManager & fsManager = FieldSpecificationManager::getInstance(); + + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, + MeshLevel & mesh, + string_array const & ) + { + + // 1. Apply pressure Dirichlet BCs, store in a separate field + applyFieldValue< ElementSubRegionBase >( time_n, dt, mesh, bcLogMessage, + fields::flow::pressure::key(), fields::flow::bcPressure::key() ); + // 2. Apply saturation BC (phase volume fraction) and store in a separate field + applyFieldValue< ElementSubRegionBase >( time_n, dt, mesh, bcLogMessage, + fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key(), + fields::immiscibleMultiphaseFlow::bcPhaseVolumeFraction::key() ); + + globalIndex const rankOffset = dofManager.rankOffset(); + string const dofKey = dofManager.getKey( viewKeyStruct::elemDofFieldString() ); + + // 3. Call constitutive update + fsManager.apply< ElementSubRegionBase >( time_n + dt, + mesh, + fields::flow::pressure::key(), + [&] ( FieldSpecificationBase const &, + string const &, + SortedArrayView< localIndex const > const & targetSet, + ElementSubRegionBase & subRegion, + string const & ) + { + + arrayView1d< real64 const > const bcPres = + subRegion.getReference< array1d< real64 > >( fields::flow::bcPressure::key() ); + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const bcPhaseVolFraction = + subRegion.getReference< array2d< real64, immiscibleFlow::LAYOUT_PHASE > >( + fields::immiscibleMultiphaseFlow::bcPhaseVolumeFraction::key() ); + + arrayView1d< integer const > const ghostRank = + subRegion.getReference< array1d< integer > >( ObjectManagerBase::viewKeyStruct::ghostRankString() ); + arrayView1d< globalIndex const > const dofNumber = + subRegion.getReference< array1d< globalIndex > >( dofKey ); + arrayView1d< real64 const > const pres = + subRegion.getReference< array1d< real64 > >( fields::flow::pressure::key() ); + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFraction = + subRegion.getReference< array2d< real64, immiscibleFlow::LAYOUT_PHASE > >( + fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key() ); + + integer const numPhase = m_numPhases; + + + forAll< parallelDevicePolicy<> >( targetSet.size(), [=] GEOS_HOST_DEVICE ( localIndex const a ) + { + localIndex const ei = targetSet[a]; + if( ghostRank[ei] >= 0 ) + { + return; + } + + globalIndex const dofIndex = dofNumber[ei]; + localIndex const localRow = dofIndex - rankOffset; + real64 rhsValue; + + // 3.1. Apply pressure value to the matrix/rhs + FieldSpecificationEqual::SpecifyFieldValue( dofIndex, + rankOffset, + localMatrix, + rhsValue, + bcPres[ei], + pres[ei] ); + localRhs[localRow] = rhsValue; + + // 3.2. For each phase, apply target saturation value + for( integer ip = 0; ip < numPhase-1; ++ip ) + { + FieldSpecificationEqual::SpecifyFieldValue( dofIndex + ip + 1, + rankOffset, + localMatrix, + rhsValue, + bcPhaseVolFraction[ei][ip], + phaseVolFraction[ei][ip] ); + localRhs[localRow + ip + 1] = rhsValue; + } + } ); + } ); + } ); + } + + void ImmiscibleMultiphaseFlow::applySourceFluxBC( real64 const time, + real64 const dt, + DofManager const & dofManager, + DomainPartition & domain, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) const + { + GEOS_MARK_FUNCTION; + + FieldSpecificationManager & fsManager = FieldSpecificationManager::getInstance(); + + string const dofKey = dofManager.getKey( viewKeyStruct::elemDofFieldString() ); + + // Step 1: count individual source flux boundary conditions + + std::map< string, localIndex > bcNameToBcId; + localIndex bcCounter = 0; + + fsManager.forSubGroups< SourceFluxBoundaryCondition >( [&] ( SourceFluxBoundaryCondition const & bc ) + { + // collect all the bc names to idx + bcNameToBcId[bc.getName()] = bcCounter; + bcCounter++; + } ); + + if( bcCounter == 0 ) + { + return; + } + + // Step 2: count the set size for each source flux (each source flux may have multiple target sets) + + array1d< globalIndex > bcAllSetsSize( bcNameToBcId.size() ); + + computeSourceFluxSizeScalingFactor( time, + dt, + domain, + bcNameToBcId, + bcAllSetsSize.toView() ); + + // Step 3: we are ready to impose the boundary condition, normalized by the set size + + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, MeshLevel & mesh, + string_array const & ) + { + + fsManager.apply< ElementSubRegionBase, + SourceFluxBoundaryCondition >( time + dt, + mesh, + SourceFluxBoundaryCondition::catalogName(), + [&]( SourceFluxBoundaryCondition const & fs, + string const & setName, + SortedArrayView< localIndex const > const & targetSet, + ElementSubRegionBase & subRegion, + string const & ) + { + if( fs.getLogLevel() >= 1 && m_nonlinearSolverParameters.m_numNewtonIterations == 0 ) + { + globalIndex const numTargetElems = MpiWrapper::sum< globalIndex >( targetSet.size() ); + GEOS_LOG_RANK_0( GEOS_FMT( bcLogMessage, + getName(), time+dt, fs.getCatalogName(), fs.getName(), + setName, subRegion.getName(), fs.getScale(), numTargetElems ) ); + } + + if( targetSet.size() == 0 ) + { + return; + } + if( !subRegion.hasWrapper( dofKey ) ) + { + if( fs.getLogLevel() >= 1 ) + { + GEOS_LOG_RANK( GEOS_FMT( "{}: trying to apply SourceFlux, but its targetSet named '{}' intersects with non-simulated region named '{}'.", + getDataContext(), setName, subRegion.getName() ) ); + } + return; + } + + arrayView1d< globalIndex const > const dofNumber = subRegion.getReference< array1d< globalIndex > >( dofKey ); + arrayView1d< integer const > const ghostRank = subRegion.ghostRank(); + + // Step 3.1: get the values of the source boundary condition that need to be added to the rhs + + array1d< globalIndex > dofArray( targetSet.size() ); + array1d< real64 > rhsContributionArray( targetSet.size() ); + arrayView1d< real64 > rhsContributionArrayView = rhsContributionArray.toView(); + localIndex const rankOffset = dofManager.rankOffset(); + + RAJA::ReduceSum< parallelDeviceReduce, real64 > massProd( 0.0 ); + + // note that the dofArray will not be used after this step (simpler to use dofNumber instead) + fs.computeRhsContribution< FieldSpecificationAdd, + parallelDevicePolicy<> >( targetSet.toViewConst(), + time + dt, + dt, + subRegion, + dofNumber, + rankOffset, + localMatrix, + dofArray.toView(), + rhsContributionArrayView, + [] GEOS_HOST_DEVICE ( localIndex const ) + { + return 0.0; + } ); + + // Step 3.2: we are ready to add the right-hand side contributions, taking into account our equation layout + + // get the normalizer + real64 const sizeScalingFactor = bcAllSetsSize[bcNameToBcId.at( fs.getName())]; + integer const fluidPhaseId = fs.getComponent(); + integer const numFluidPhases = m_numPhases; + integer useTotalMassEquation = m_useTotalMassEquation; + forAll< parallelDevicePolicy<> >( targetSet.size(), [sizeScalingFactor, + targetSet, + rankOffset, + ghostRank, + fluidPhaseId, + numFluidPhases, + useTotalMassEquation, + dofNumber, + rhsContributionArrayView, + localRhs, + massProd] GEOS_HOST_DEVICE ( localIndex const a ) + { + // we need to filter out ghosts here, because targetSet may contain them + localIndex const ei = targetSet[a]; + if( ghostRank[ei] >= 0 ) + { + return; + } + + real64 const rhsValue = rhsContributionArrayView[a] / sizeScalingFactor; // scale the contribution by the sizeScalingFactor here! + massProd += rhsValue; + if( useTotalMassEquation > 0 ) + { + // for all "fluid components", we add the value to the total mass balance equation + globalIndex const totalMassBalanceRow = dofNumber[ei] - rankOffset; + localRhs[totalMassBalanceRow] += rhsValue; + if( fluidPhaseId < numFluidPhases - 1 ) + { + globalIndex const compMassBalanceRow = totalMassBalanceRow + fluidPhaseId + 1; // component mass bal equations are shifted + localRhs[compMassBalanceRow] += rhsValue; + } + } + else + { + globalIndex const compMassBalanceRow = dofNumber[ei] - rankOffset + fluidPhaseId; + localRhs[compMassBalanceRow] += rhsValue; + } + } ); + + SourceFluxStatsAggregator::forAllFluxStatWrappers( subRegion, fs.getName(), + [&]( SourceFluxStatsAggregator::WrappedStats & wrapper ) + { + // set the new sub-region statistics for this timestep + array1d< real64 > massProdArr{ m_numPhases }; + massProdArr[fluidPhaseId] = massProd.get(); + wrapper.gatherTimeStepStats( time, dt, massProdArr.toViewConst(), targetSet.size() ); + } ); + } ); + } ); + } + + real64 ImmiscibleMultiphaseFlow::calculateResidualNorm( real64 const & GEOS_UNUSED_PARAM( time_n ), + real64 const & GEOS_UNUSED_PARAM( dt ), + DomainPartition const & domain, + DofManager const & dofManager, + arrayView1d< real64 const > const & localRhs ) + { + GEOS_MARK_FUNCTION; + array1d< real64 > localResidualNorm; + array1d< real64 > localResidualNormalizer; + localResidualNorm.resize( numNorm ); + localResidualNormalizer.resize( numNorm ); + + physicsSolverBaseKernels::NormType const normType = getNonlinearSolverParameters().normType(); + + globalIndex const rankOffset = dofManager.rankOffset(); + string const dofKey = dofManager.getKey( viewKeyStruct::elemDofFieldString() ); + + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, + MeshLevel const & mesh, string_array const & regionNames ) - { - stdVector< string > fields{ fields::flow::pressure::key(), fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key() }; - - FieldIdentifiers fieldsToBeSync; - fieldsToBeSync.addElementFields( fields, regionNames ); - - CommunicationTools::getInstance().synchronizeFields( fieldsToBeSync, mesh, domain.getNeighbors(), true ); - } ); -} - - -void ImmiscibleMultiphaseFlow::updateVolumeConstraint( ElementSubRegionBase & subRegion ) const -{ - GEOS_MARK_FUNCTION; - - arrayView2d< real64, immiscibleFlow::USD_PHASE > const phaseVolumeFraction = subRegion.getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); - - forAll< parallelDevicePolicy<> >( subRegion.size(), [=] GEOS_HOST_DEVICE ( localIndex const ei ) - { - phaseVolumeFraction[ei][1] = 1.0 - phaseVolumeFraction[ei][0]; - } ); -} - - -void ImmiscibleMultiphaseFlow::resetStateToBeginningOfStep( DomainPartition & domain ) -{ - GEOS_MARK_FUNCTION; - - forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, - MeshLevel & mesh, - string_array const & regionNames ) - { - mesh.getElemManager().forElementSubRegions< CellElementSubRegion, - SurfaceElementSubRegion >( regionNames, - [&]( localIndex const, - auto & subRegion ) - { - arrayView1d< real64 > const & pres = - subRegion.template getField< fields::flow::pressure >(); - arrayView1d< real64 const > const & pres_n = - subRegion.template getField< fields::flow::pressure_n >(); - pres.setValues< parallelDevicePolicy<> >( pres_n ); - - // after the update, save the new saturation - arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFrac_n = - subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction_n >(); - - arrayView2d< real64, immiscibleFlow::USD_PHASE > const phaseVolFrac = - subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); - phaseVolFrac.setValues< parallelDevicePolicy<> >( phaseVolFrac_n ); - - arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const & phaseMass_n = - subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseMass_n >(); - - arrayView2d< real64, immiscibleFlow::USD_PHASE > const & phaseMass = - subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseMass >(); - phaseMass.setValues< parallelDevicePolicy<> >( phaseMass_n ); - - if( m_isThermal ) - { - arrayView1d< real64 > const & temp = - subRegion.template getField< fields::flow::temperature >(); - arrayView1d< real64 const > const & temp_n = - subRegion.template getField< fields::flow::temperature_n >(); - temp.setValues< parallelDevicePolicy<> >( temp_n ); - } - - // update porosity, permeability - updatePorosityAndPermeability( subRegion ); - // update all fluid properties - updateFluidState( subRegion ); - } ); - } ); -} - -void ImmiscibleMultiphaseFlow::implicitStepComplete( real64 const & time, - real64 const & dt, + { + mesh.getElemManager().forElementSubRegions( regionNames, + [&]( localIndex const, + ElementSubRegionBase const & subRegion ) + { + real64 subRegionResidualNorm[numNorm]{}; + real64 subRegionResidualNormalizer[numNorm]{}; + + string const & solidName = subRegion.getReference< string >( viewKeyStruct::solidNamesString() ); + CoupledSolidBase const & solid = getConstitutiveModel< CoupledSolidBase >( subRegion, solidName ); + + // step 1: compute the norm in the subRegion + + real64 subRegionFlowResidualNorm[1]{}; + real64 subRegionFlowResidualNormalizer[1]{}; + + immiscibleMultiphaseKernels:: + ResidualNormKernelFactory::createAndLaunch< parallelDevicePolicy<> >( normType, + 2, + rankOffset, + dofKey, + localRhs, + subRegion, + solid, + m_nonlinearSolverParameters.m_minNormalizer, + subRegionFlowResidualNorm, + subRegionFlowResidualNormalizer ); + subRegionResidualNorm[0] = subRegionFlowResidualNorm[0]; + subRegionResidualNormalizer[0] = subRegionFlowResidualNormalizer[0]; + + // step 2: first reduction across meshBodies/regions/subRegions + if( normType == physicsSolverBaseKernels::NormType::Linf ) + { + physicsSolverBaseKernels::LinfResidualNormHelper:: + updateLocalNorm< numNorm >( subRegionResidualNorm, localResidualNorm ); + } + else + { + physicsSolverBaseKernels::L2ResidualNormHelper:: + updateLocalNorm< numNorm >( subRegionResidualNorm, subRegionResidualNormalizer, localResidualNorm, localResidualNormalizer ); + } + } ); + } ); + + real64 residualNorm = 0.0; + residualNorm = localResidualNorm[0]; + if( normType == physicsSolverBaseKernels::NormType::Linf ) + { + physicsSolverBaseKernels::LinfResidualNormHelper::computeGlobalNorm( localResidualNorm[0], residualNorm ); + } + else + { + physicsSolverBaseKernels::L2ResidualNormHelper::computeGlobalNorm( localResidualNorm[0], localResidualNormalizer[0], residualNorm ); + } + + if( getLogLevel() >= 1 && logger::internal::rank == 0 ) + { + std::cout << GEOS_FMT( " ( R{} ) = ( {:4.2e} )", coupledSolverAttributePrefix(), residualNorm ); + } + + return residualNorm; + } + + void ImmiscibleMultiphaseFlow::applySystemSolution( DofManager const & dofManager, + arrayView1d< real64 const > const & localSolution, + real64 const scalingFactor, + real64 const dt, DomainPartition & domain ) -{ - // Step 1: save the converged aquifer state - // note: we have to save the aquifer state **before** updating the pressure, - // otherwise the aquifer flux is saved with the wrong pressure time level - saveAquiferConvergedState( time, dt, domain ); - - forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, - MeshLevel & mesh, - string_array const & regionNames ) - { - mesh.getElemManager().forElementSubRegions( regionNames, - [&]( localIndex const, - ElementSubRegionBase & subRegion ) - { - // Step 3: save the converged solid state - string const & solidName = subRegion.getReference< string >( viewKeyStruct::solidNamesString() ); - CoupledSolidBase const & porousMaterial = getConstitutiveModel< CoupledSolidBase >( subRegion, solidName ); - if( m_keepVariablesConstantDuringInitStep ) - { - porousMaterial.ignoreConvergedState(); // newPorosity <- porosity_n - } - else - { - porousMaterial.saveConvergedState(); // porosity_n <- porosity - } - - // Step 4: save converged state for the relperm model to handle hysteresis - arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFrac = - subRegion.getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); - string const & relPermName = subRegion.getReference< string >( viewKeyStruct::relPermNamesString() ); - RelativePermeabilityBase const & relPermMaterial = - getConstitutiveModel< RelativePermeabilityBase >( subRegion, relPermName ); - relPermMaterial.saveConvergedPhaseVolFractionState( phaseVolFrac ); - - // Step 5: if capillary pressure is supported, send the converged porosity and permeability to the capillary pressure model - // note: this is needed when the capillary pressure depends on porosity and permeability (Leverett J-function for instance) - if( m_hasCapPressure ) - { - arrayView2d< real64 const > const porosity = porousMaterial.getPorosity(); - - string const & permName = subRegion.getReference< string >( viewKeyStruct::permeabilityNamesString() ); - PermeabilityBase const & permeabilityMaterial = - getConstitutiveModel< PermeabilityBase >( subRegion, permName ); - arrayView3d< real64 const > const permeability = permeabilityMaterial.permeability(); - - string const & capPressName = subRegion.getReference< string >( viewKeyStruct::capPressureNamesString() ); - CapillaryPressureBase const & capPressureMaterial = - getConstitutiveModel< CapillaryPressureBase >( subRegion, capPressName ); - capPressureMaterial.saveConvergedRockState( porosity, permeability ); - } - } ); - } ); - -} - -void ImmiscibleMultiphaseFlow::saveConvergedState( ElementSubRegionBase & subRegion ) const -{ - FlowSolverBase::saveConvergedState( subRegion ); - - arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFrac = - subRegion.getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); - arrayView2d< real64, immiscibleFlow::USD_PHASE > const phaseVolFrac_n = - subRegion.getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction_n >(); - phaseVolFrac_n.setValues< parallelDevicePolicy<> >( phaseVolFrac ); - - arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseMass = - subRegion.getField< fields::immiscibleMultiphaseFlow::phaseMass >(); - arrayView2d< real64, immiscibleFlow::USD_PHASE > const phaseMass_n = - subRegion.getField< fields::immiscibleMultiphaseFlow::phaseMass_n >(); - phaseMass_n.setValues< parallelDevicePolicy<> >( phaseMass ); - -} - -void ImmiscibleMultiphaseFlow::updateState( DomainPartition & domain ) -{ - GEOS_MARK_FUNCTION; - - forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, - MeshLevel & mesh, - string_array const & regionNames ) - { - mesh.getElemManager().forElementSubRegions< CellElementSubRegion, - SurfaceElementSubRegion >( regionNames, [&]( localIndex const, - auto & subRegion ) - { - // update porosity, permeability, and solid internal energy - updatePorosityAndPermeability( subRegion ); - // update all fluid properties - updateVolumeConstraint( subRegion ); - updateFluidState( subRegion ); - } ); - } ); -} - -real64 ImmiscibleMultiphaseFlow::setNextDtBasedOnStateChange( real64 const & currentDt, - DomainPartition & domain ) -{ - if( m_targetRelativePresChange >= 1.0 && - m_targetPhaseVolFracChange >= 1.0 ) - { - return LvArray::NumericLimits< real64 >::max; - } - - real64 maxRelativePresChange = 0.0; - real64 maxAbsolutePhaseVolFracChange = 0.0; - - integer const numPhase = m_numPhases; - - forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, - MeshLevel & mesh, - string_array const & regionNames ) - { - mesh.getElemManager().forElementSubRegions( regionNames, - [&]( localIndex const, - ElementSubRegionBase & subRegion ) - { - arrayView1d< integer const > const ghostRank = subRegion.ghostRank(); - - arrayView1d< real64 const > const pres = subRegion.getField< fields::flow::pressure >(); - arrayView1d< real64 const > const pres_n = subRegion.getField< fields::flow::pressure_n >(); - arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFrac = - subRegion.getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); - arrayView2d< real64, immiscibleFlow::USD_PHASE > const phaseVolFrac_n = - subRegion.getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction_n >(); - - RAJA::ReduceMax< parallelDeviceReduce, real64 > subRegionMaxPresChange( 0.0 ); - RAJA::ReduceMax< parallelDeviceReduce, real64 > subRegionMaxPhaseVolFracChange( 0.0 ); - - forAll< parallelDevicePolicy<> >( subRegion.size(), [=] GEOS_HOST_DEVICE ( localIndex const ei ) - { - if( ghostRank[ei] < 0 ) - { - // switch from relative to absolute when values less than 1 - subRegionMaxPresChange.max( LvArray::math::abs( pres[ei] - pres_n[ei] ) / LvArray::math::max( LvArray::math::abs( pres_n[ei] ), 1.0 ) ); - for( integer ip = 0; ip < numPhase; ++ip ) - { - subRegionMaxPhaseVolFracChange.max( LvArray::math::abs( phaseVolFrac[ei][ip] - phaseVolFrac_n[ei][ip] ) ); - } - } - } ); - - maxRelativePresChange = LvArray::math::max( maxRelativePresChange, subRegionMaxPresChange.get() ); - maxAbsolutePhaseVolFracChange = LvArray::math::max( maxAbsolutePhaseVolFracChange, subRegionMaxPhaseVolFracChange.get() ); - - } ); - } ); - - maxRelativePresChange = MpiWrapper::max( maxRelativePresChange ); - maxAbsolutePhaseVolFracChange = MpiWrapper::max( maxAbsolutePhaseVolFracChange ); - - GEOS_LOG_LEVEL_RANK_0( logInfo::TimeStep, GEOS_FMT( "{}: max relative pressure change during time step = {} %", - getName(), GEOS_FMT( "{:.{}f}", 100*maxRelativePresChange, 3 ) ) ); - GEOS_LOG_LEVEL_RANK_0( logInfo::TimeStep, GEOS_FMT( "{}: max absolute phase volume fraction change during time step = {}", - getName(), GEOS_FMT( "{:.{}f}", maxAbsolutePhaseVolFracChange, 3 ) ) ); - - real64 const eps = LvArray::NumericLimits< real64 >::epsilon; - - real64 const nextDtPressure = currentDt * ( 1.0 + m_solutionChangeScalingFactor ) * m_targetRelativePresChange - / std::max( eps, maxRelativePresChange + m_solutionChangeScalingFactor * m_targetRelativePresChange ); - if( m_nonlinearSolverParameters.getLogLevel() > 0 ) - GEOS_LOG_RANK_0( GEOS_FMT( "{}: next time step based on pressure change = {}", getName(), nextDtPressure )); - real64 const nextDtPhaseVolFrac = currentDt * ( 1.0 + m_solutionChangeScalingFactor ) * m_targetPhaseVolFracChange - / std::max( eps, maxAbsolutePhaseVolFracChange + m_solutionChangeScalingFactor * m_targetPhaseVolFracChange ); - if( m_nonlinearSolverParameters.getLogLevel() > 0 ) - GEOS_LOG_RANK_0( GEOS_FMT( "{}: next time step based on phase volume fraction change = {}", getName(), nextDtPhaseVolFrac )); - - return std::min( nextDtPressure, nextDtPhaseVolFrac ); - -} - -REGISTER_CATALOG_ENTRY( PhysicsSolverBase, ImmiscibleMultiphaseFlow, string const &, Group * const ) - -} // namespace geos + { + GEOS_UNUSED_VAR( dt ); + + DofManager::CompMask pressureMask( m_numDofPerCell, 0, 1 ); + + // 1. apply the pressure update + dofManager.addVectorToField( localSolution, + viewKeyStruct::elemDofFieldString(), + fields::flow::pressure::key(), + scalingFactor, + pressureMask ); + + // 2. apply the phaseVolumeFraction update + dofManager.addVectorToField( localSolution, + viewKeyStruct::elemDofFieldString(), + fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key(), + scalingFactor, + ~pressureMask ); + + // 3. synchronize + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&] ( string const &, + MeshLevel & mesh, + string_array const & regionNames ) + { + std::vector< string > fields{ fields::flow::pressure::key(), fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key() }; + + FieldIdentifiers fieldsToBeSync; + fieldsToBeSync.addElementFields( fields, regionNames ); + + CommunicationTools::getInstance().synchronizeFields( fieldsToBeSync, mesh, domain.getNeighbors(), true ); + } ); + } + + + void ImmiscibleMultiphaseFlow::updateVolumeConstraint( ElementSubRegionBase & subRegion ) const + { + GEOS_MARK_FUNCTION; + + arrayView2d< real64, immiscibleFlow::USD_PHASE > const phaseVolumeFraction = subRegion.getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); + + forAll< parallelDevicePolicy<> >( subRegion.size(), [=] GEOS_HOST_DEVICE ( localIndex const ei ) + { + phaseVolumeFraction[ei][0] = fmin( 1.0, fmax( phaseVolumeFraction[ei][0], 0.0 )); ; + phaseVolumeFraction[ei][1] = 1.0 - phaseVolumeFraction[ei][0]; + } ); + } + + + void ImmiscibleMultiphaseFlow::resetStateToBeginningOfStep( DomainPartition & domain ) + { + GEOS_MARK_FUNCTION; + + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, + MeshLevel & mesh, + string_array const & regionNames ) + { + mesh.getElemManager().forElementSubRegions< CellElementSubRegion, + SurfaceElementSubRegion >( regionNames, + [&]( localIndex const, + auto & subRegion ) + { + arrayView1d< real64 > const & pres = + subRegion.template getField< fields::flow::pressure >(); + arrayView1d< real64 const > const & pres_n = + subRegion.template getField< fields::flow::pressure_n >(); + pres.setValues< parallelDevicePolicy<> >( pres_n ); + + // after the update, save the new saturation + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFrac_n = + subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction_n >(); + + arrayView2d< real64, immiscibleFlow::USD_PHASE > const phaseVolFrac = + subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); + phaseVolFrac.setValues< parallelDevicePolicy<> >( phaseVolFrac_n ); + + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const & phaseMass_n = + subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseMass_n >(); + + arrayView2d< real64, immiscibleFlow::USD_PHASE > const & phaseMass = + subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseMass >(); + phaseMass.setValues< parallelDevicePolicy<> >( phaseMass_n ); + + if( m_isThermal ) + { + arrayView1d< real64 > const & temp = + subRegion.template getField< fields::flow::temperature >(); + arrayView1d< real64 const > const & temp_n = + subRegion.template getField< fields::flow::temperature_n >(); + temp.setValues< parallelDevicePolicy<> >( temp_n ); + } + + // update porosity, permeability + updatePorosityAndPermeability( subRegion ); + // update all fluid properties + updateFluidState( subRegion ); + } ); + } ); + } + + void ImmiscibleMultiphaseFlow::implicitStepComplete( real64 const & time, + real64 const & dt, + DomainPartition & domain ) + { + // Step 1: save the converged aquifer state + // note: we have to save the aquifer state **before** updating the pressure, + // otherwise the aquifer flux is saved with the wrong pressure time level + saveAquiferConvergedState( time, dt, domain ); + + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, + MeshLevel & mesh, + string_array const & regionNames ) + { + mesh.getElemManager().forElementSubRegions( regionNames, + [&]( localIndex const, + ElementSubRegionBase & subRegion ) + { + // Step 3: save the converged solid state + string const & solidName = subRegion.getReference< string >( viewKeyStruct::solidNamesString() ); + CoupledSolidBase const & porousMaterial = getConstitutiveModel< CoupledSolidBase >( subRegion, solidName ); + if( m_keepVariablesConstantDuringInitStep ) + { + porousMaterial.ignoreConvergedState(); // newPorosity <- porosity_n + } + else + { + porousMaterial.saveConvergedState(); // porosity_n <- porosity + } + + // Step 4: save converged state for the relperm model to handle hysteresis + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFrac = + subRegion.getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); + string const & relPermName = subRegion.getReference< string >( viewKeyStruct::relPermNamesString() ); + RelativePermeabilityBase const & relPermMaterial = + getConstitutiveModel< RelativePermeabilityBase >( subRegion, relPermName ); + relPermMaterial.saveConvergedPhaseVolFractionState( phaseVolFrac ); + + // Step 5: if capillary pressure is supported, send the converged porosity and permeability to the capillary pressure model + // note: this is needed when the capillary pressure depends on porosity and permeability (Leverett J-function for instance) + if( m_hasCapPressure ) + { + arrayView2d< real64 const > const porosity = porousMaterial.getPorosity(); + + string const & permName = subRegion.getReference< string >( viewKeyStruct::permeabilityNamesString() ); + PermeabilityBase const & permeabilityMaterial = + getConstitutiveModel< PermeabilityBase >( subRegion, permName ); + arrayView3d< real64 const > const permeability = permeabilityMaterial.permeability(); + + string const & capPressName = subRegion.getReference< string >( viewKeyStruct::capPressureNamesString() ); + CapillaryPressureBase const & capPressureMaterial = + getConstitutiveModel< CapillaryPressureBase >( subRegion, capPressName ); + capPressureMaterial.saveConvergedRockState( porosity, permeability ); + } + } ); + } ); + } + + void ImmiscibleMultiphaseFlow::saveConvergedState( ElementSubRegionBase & subRegion ) const + { + FlowSolverBase::saveConvergedState( subRegion ); + + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFrac = + subRegion.getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); + arrayView2d< real64, immiscibleFlow::USD_PHASE > const phaseVolFrac_n = + subRegion.getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction_n >(); + phaseVolFrac_n.setValues< parallelDevicePolicy<> >( phaseVolFrac ); + + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseMass = + subRegion.getField< fields::immiscibleMultiphaseFlow::phaseMass >(); + arrayView2d< real64, immiscibleFlow::USD_PHASE > const phaseMass_n = + subRegion.getField< fields::immiscibleMultiphaseFlow::phaseMass_n >(); + phaseMass_n.setValues< parallelDevicePolicy<> >( phaseMass ); + + } + + void ImmiscibleMultiphaseFlow::updateState( DomainPartition & domain ) + { + GEOS_MARK_FUNCTION; + + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, + MeshLevel & mesh, + string_array const & regionNames ) + { + mesh.getElemManager().forElementSubRegions< CellElementSubRegion, + SurfaceElementSubRegion >( regionNames, [&]( localIndex const, + auto & subRegion ) + { + // update porosity, permeability, and solid internal energy + updatePorosityAndPermeability( subRegion ); + // update all fluid properties + updateVolumeConstraint( subRegion ); + updateFluidState( subRegion ); + } ); + } ); + } + + real64 ImmiscibleMultiphaseFlow::setNextDtBasedOnStateChange( real64 const & currentDt, + DomainPartition & domain ) + { + if( m_targetRelativePresChange >= 1.0 && + m_targetPhaseVolFracChange >= 1.0 ) + { + return LvArray::NumericLimits< real64 >::max; + } + + real64 maxRelativePresChange = 0.0; + real64 maxAbsolutePhaseVolFracChange = 0.0; + + integer const numPhase = m_numPhases; + + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, + MeshLevel & mesh, + string_array const & regionNames ) + { + mesh.getElemManager().forElementSubRegions( regionNames, + [&]( localIndex const, + ElementSubRegionBase & subRegion ) + { + arrayView1d< integer const > const ghostRank = subRegion.ghostRank(); + + arrayView1d< real64 const > const pres = subRegion.getField< fields::flow::pressure >(); + arrayView1d< real64 const > const pres_n = subRegion.getField< fields::flow::pressure_n >(); + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFrac = + subRegion.getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); + arrayView2d< real64, immiscibleFlow::USD_PHASE > const phaseVolFrac_n = + subRegion.getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction_n >(); + + RAJA::ReduceMax< parallelDeviceReduce, real64 > subRegionMaxPresChange( 0.0 ); + RAJA::ReduceMax< parallelDeviceReduce, real64 > subRegionMaxPhaseVolFracChange( 0.0 ); + + forAll< parallelDevicePolicy<> >( subRegion.size(), [=] GEOS_HOST_DEVICE ( localIndex const ei ) + { + if( ghostRank[ei] < 0 ) + { + // switch from relative to absolute when values less than 1 + subRegionMaxPresChange.max( LvArray::math::abs( pres[ei] - pres_n[ei] ) / LvArray::math::max( LvArray::math::abs( pres_n[ei] ), 1.0 ) ); + for( integer ip = 0; ip < numPhase; ++ip ) + { + subRegionMaxPhaseVolFracChange.max( LvArray::math::abs( phaseVolFrac[ei][ip] - phaseVolFrac_n[ei][ip] ) ); + } + } + } ); + + maxRelativePresChange = LvArray::math::max( maxRelativePresChange, subRegionMaxPresChange.get() ); + maxAbsolutePhaseVolFracChange = LvArray::math::max( maxAbsolutePhaseVolFracChange, subRegionMaxPhaseVolFracChange.get() ); + + } ); + } ); + + maxRelativePresChange = MpiWrapper::max( maxRelativePresChange ); + maxAbsolutePhaseVolFracChange = MpiWrapper::max( maxAbsolutePhaseVolFracChange ); + + GEOS_LOG_LEVEL_RANK_0( logInfo::TimeStep, GEOS_FMT( "{}: max relative pressure change during time step = {} %", + getName(), GEOS_FMT( "{:.{}f}", 100*maxRelativePresChange, 3 ) ) ); + GEOS_LOG_LEVEL_RANK_0( logInfo::TimeStep, GEOS_FMT( "{}: max absolute phase volume fraction change during time step = {}", + getName(), GEOS_FMT( "{:.{}f}", maxAbsolutePhaseVolFracChange, 3 ) ) ); + + real64 const eps = LvArray::NumericLimits< real64 >::epsilon; + + real64 const nextDtPressure = currentDt * ( 1.0 + m_solutionChangeScalingFactor ) * m_targetRelativePresChange + / std::max( eps, maxRelativePresChange + m_solutionChangeScalingFactor * m_targetRelativePresChange ); + if( m_nonlinearSolverParameters.getLogLevel() > 0 ) + GEOS_LOG_RANK_0( GEOS_FMT( "{}: next time step based on pressure change = {}", getName(), nextDtPressure )); + real64 const nextDtPhaseVolFrac = currentDt * ( 1.0 + m_solutionChangeScalingFactor ) * m_targetPhaseVolFracChange + / std::max( eps, maxAbsolutePhaseVolFracChange + m_solutionChangeScalingFactor * m_targetPhaseVolFracChange ); + if( m_nonlinearSolverParameters.getLogLevel() > 0 ) + GEOS_LOG_RANK_0( GEOS_FMT( "{}: next time step based on phase volume fraction change = {}", getName(), nextDtPhaseVolFrac )); + + return std::min( nextDtPressure, nextDtPhaseVolFrac ); + + } + + REGISTER_CATALOG_ENTRY( PhysicsSolverBase, ImmiscibleMultiphaseFlow, string const &, Group * const ) + + } // namespace geos + diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp index 25399a7ebc8..37b67a7852c 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp @@ -38,7 +38,7 @@ #include "constitutive/relativePermeability/RelativePermeabilityBase.hpp" #include "constitutive/relativePermeability/RelativePermeabilityFields.hpp" #include "constitutive/ConstitutiveManager.hpp" -#include "constitutive/capillaryPressure/capillaryPressureSelector.hpp" +#include "constitutive/capillaryPressure/CapillaryPressureSelector.hpp" #include "constitutive/relativePermeability/RelativePermeabilitySelector.hpp" #include "constitutive/ConstitutivePassThru.hpp" @@ -959,11 +959,11 @@ static void local_solver( real64 uT, stdVector< real64 > saturations, stdVector< dC1_dS[ip][ke] = dC_dS_term1 + dC_dS_term2 * dC_dS_term3; dhalfFlux1_dP[ip][ke] -= dC_dP; dhalfFlux1_dS[ip][ke] -= dC1_dS[ip][ke]; - // if (std::fabs(facePhaseVolFrac1[0][0] - 1.0) > 1e-8){ + if (std::fabs(facePhaseVolFrac1[0][0] - 1.0) > 1e-8){ dC1_dpc[ip][ke] = dC1_dS[ip][ke] * dfacePhaseVolFrac_dCapPres1[0][0][0][0]; - // } else { - // dC1_dpc[ip][ke] = dC_dS_term1 * dfacePhaseVolFrac_dCapPres1[0][0][0][0]; - // } + } else { + dC1_dpc[ip][ke] = dC_dS_term1 * dfacePhaseVolFrac_dCapPres1[0][0][0][0]; + } // GEOS_UNUSED_VAR( dC1_dpc[ip][ke] ); } @@ -972,11 +972,11 @@ static void local_solver( real64 uT, stdVector< real64 > saturations, stdVector< dC2_dS[ip][ke] = dC_dS_term1 + dC_dS_term2 * dC_dS_term3; dhalfFlux2_dP[ip][ke] -= dC_dP; dhalfFlux2_dS[ip][ke] -= dC2_dS[ip][ke]; - // if (std::fabs(facePhaseVolFrac2[0][0] - 1.0) > 1e-8){ + if (std::fabs(facePhaseVolFrac2[0][0] - 1.0) > 1e-8){ dC2_dpc[ip][ke] = dC2_dS[ip][ke] * dfacePhaseVolFrac_dCapPres2[0][0][0][0]; - // } else { - // dC2_dpc[ip][ke] = dC_dS_term1 * dfacePhaseVolFrac_dCapPres2[0][0][0][0]; - // } + } else { + dC2_dpc[ip][ke] = dC_dS_term1 * dfacePhaseVolFrac_dCapPres2[0][0][0][0]; + } // GEOS_UNUSED_VAR( dC2_dpc[ip][ke] ); } @@ -1040,7 +1040,7 @@ static void local_solver( real64 uT, stdVector< real64 > saturations, stdVector< } else { - if( std::fabs( halfFluxVal[ip][0] ) < 1e-20 ) + if( std::fabs( halfFluxVal[ip][0] ) < 1e-20 ) { k_up_0_check[ip] = k_up_0_b; } @@ -1106,6 +1106,9 @@ static void local_solver( real64 uT, stdVector< real64 > saturations, stdVector< // Check convergence if( std::fabs( local_residual ) < tol ) { + // if( std::fabs( dhalfFlux_dpc[0][0] - dhalfFlux_dpc[0][1] ) saturations, stdVector< real64 deltaPc = local_residual/local_jacobian; - // if (std::fabs(facePhaseVolFrac1[0][0] - 1.0) < 1e-5 && (std::fabs(deltaPc * dfacePhaseVolFrac_dCapPres2[0][0][0][0]) < 0.05)){ - // ext_iter0++; - // } - // if (std::fabs(facePhaseVolFrac2[0][0] - 1.0) < 1e-5 && (std::fabs(deltaPc * dfacePhaseVolFrac_dCapPres1[0][0][0][0]) < 0.05)){ - // ext_iter1++; - // } - - // if (ext_iter0 > 20){ - // halfFluxVal[0][1] = halfFluxVal[0][0]; - // halfFluxVal[1][1] = halfFluxVal[1][0]; - // local_residual = halfFluxVal[0][0] - halfFluxVal[0][1]; - // } - - // if (ext_iter1 > 20){ - // halfFluxVal[0][0] = halfFluxVal[0][1]; - // halfFluxVal[1][0] = halfFluxVal[1][1]; - // local_residual = halfFluxVal[0][0] - halfFluxVal[0][1]; - // } - if( std::fabs( local_residual ) < tol ) { + // if( std::fabs( dhalfFlux_dpc[0][0] - dhalfFlux_dpc[0][1] ) < eps2 ) { + // std::cout << "**********************ZeroJacobian*******************" << std::endl; + // } converged = 1; break; // Converged } @@ -1351,10 +1338,11 @@ class FluxComputeKernelBase fields::twophaseimmisciblefluid::dPhaseViscosity >; using CapPressureAccessors = - StencilMaterialAccessors< JFunctionCapillaryPressure, + StencilMaterialAccessors< BrooksCoreyCapillaryPressure, fields::cappres::phaseCapPressure, - fields::cappres::dPhaseCapPressure_dPhaseVolFraction, - fields::cappres::jFuncMultiplier >; + fields::cappres::dPhaseCapPressure_dPhaseVolFraction + >; + // ,fields::cappres::jFuncMultiplier >; using PermeabilityAccessors = @@ -1411,7 +1399,7 @@ class FluxComputeKernelBase m_dVisc_dPres( fluidAccessors.get( fields::twophaseimmisciblefluid::dPhaseViscosity {} ) ), m_phaseCapPressure( capPressureAccessors.get( fields::cappres::phaseCapPressure {} ) ), m_dPhaseCapPressure_dPhaseVolFrac( capPressureAccessors.get( fields::cappres::dPhaseCapPressure_dPhaseVolFraction {} ) ), - m_jFuncMultiplier( capPressureAccessors.get( fields::cappres::jFuncMultiplier {} ) ), + // m_jFuncMultiplier( capPressureAccessors.get( fields::cappres::jFuncMultiplier {} ) ), m_localMatrix( localMatrix ), m_localRhs( localRhs ), m_hasCapPressure ( hasCapPressure ), @@ -1460,7 +1448,7 @@ class FluxComputeKernelBase /// Views on capillary pressure ElementViewConst< arrayView3d< real64 const, cappres::USD_CAPPRES > > const m_phaseCapPressure; ElementViewConst< arrayView4d< real64 const, cappres::USD_CAPPRES_DS > > const m_dPhaseCapPressure_dPhaseVolFrac; - ElementViewConst< arrayView2d< real64 const > > const m_jFuncMultiplier; + // ElementViewConst< arrayView2d< real64 const > > const m_jFuncMultiplier; // Residual and jacobian @@ -2029,7 +2017,8 @@ class FluxComputeKernel : public FluxComputeKernelBase * @tparam RELPERMWRAPPER the type of the realtive permeability wrapper * @brief Define the interface for the assembly kernel in charge of flux terms */ -template< integer NUM_EQN, integer NUM_DOF, typename STENCILWRAPPER, typename CAPPRESWRAPPER, typename RELPERMWRAPPER > +// template< integer NUM_EQN, integer NUM_DOF, typename STENCILWRAPPER, typename CAPPRESWRAPPER, typename RELPERMWRAPPER > +template< integer NUM_EQN, integer NUM_DOF, typename STENCILWRAPPER > class FluxComputeInterfaceConditionKernel : public FluxComputeKernel< NUM_EQN, NUM_DOF, STENCILWRAPPER > { public: @@ -2057,7 +2046,7 @@ class FluxComputeInterfaceConditionKernel : public FluxComputeKernel< NUM_EQN, N using Base::m_phaseVolFrac; using Base::m_phaseMass_n; using Base::m_phaseCapPressure; - using Base::m_jFuncMultiplier; + // using Base::m_jFuncMultiplier; using Base::m_dPhaseCapPressure_dPhaseVolFrac; using Base::m_dens; using Base::m_dDens_dPres; @@ -2096,8 +2085,8 @@ class FluxComputeInterfaceConditionKernel : public FluxComputeKernel< NUM_EQN, N FluxComputeInterfaceConditionKernel( integer const numPhases, globalIndex const rankOffset, STENCILWRAPPER const & stencilWrapper, - CAPPRESWRAPPER const & capPressureWrapper, - RELPERMWRAPPER const & relPermWrapper, + // CAPPRESWRAPPER const & capPressureWrapper, + // RELPERMWRAPPER const & relPermWrapper, DofNumberAccessor const & dofNumberAccessor, ImmiscibleMultiphaseFlowAccessors const & multiPhaseFlowAccessors, MultiphaseFluidAccessors const & fluidAccessors, @@ -2114,9 +2103,9 @@ class FluxComputeInterfaceConditionKernel : public FluxComputeKernel< NUM_EQN, N constitutive::CapillaryPressureBase *, constitutive::TwoPhaseImmiscibleFluid * >, 2 > > const & interfaceConstitutivePairs, unordered_map< localIndex, localIndex > const & interfaceRegionByConnector, - std::tuple< constitutive::RelativePermeabilityBase *, - constitutive::CapillaryPressureBase *, - constitutive::TwoPhaseImmiscibleFluid * > const & interfaceConstitutivePairs_temp, + // std::tuple< constitutive::RelativePermeabilityBase *, + // constitutive::CapillaryPressureBase *, + // constitutive::TwoPhaseImmiscibleFluid * > const & interfaceConstitutivePairs_temp, localIndex const GEOS_UNUSED_PARAM( domainSize ) ) : Base( numPhases, rankOffset, @@ -2132,12 +2121,13 @@ class FluxComputeInterfaceConditionKernel : public FluxComputeKernel< NUM_EQN, N hasCapPressure, useTotalMassEquation, checkPhasePresenceInGravity ), - m_capPressureWrapper( capPressureWrapper ), - m_relPermWrapper( relPermWrapper ), + // m_capPressureWrapper( capPressureWrapper ), + // m_relPermWrapper( relPermWrapper ), m_interfaceFaceSetNames( interfaceFaceSetNames ), m_interfaceConstitutivePairs( interfaceConstitutivePairs ), - m_interfaceRegionByConnector( interfaceRegionByConnector ), - m_interfaceConstitutivePairs_temp( interfaceConstitutivePairs_temp ) + m_interfaceRegionByConnector( interfaceRegionByConnector ) + // , + // m_interfaceConstitutivePairs_temp( interfaceConstitutivePairs_temp ) {} /** @@ -2163,6 +2153,7 @@ class FluxComputeInterfaceConditionKernel : public FluxComputeKernel< NUM_EQN, N } + // if (connectorHasInterfaceConditionQ){ // // Improved transmission conditions // int ammar_code = 0; @@ -2204,7 +2195,7 @@ class FluxComputeInterfaceConditionKernel : public FluxComputeKernel< NUM_EQN, N real64 dGravHead_dP[numEqn][2]{}; real64 capGrad[numEqn]{}; - real64 capPresIC[numEqn][2]{}; + // real64 capPresIC[numEqn][2]{}; real64 jFMultiplier[numEqn][2]{}; real64 dCapGrad_dP[numEqn][2]{}; real64 dCapGrad_dS[numEqn][2]{}; @@ -2245,7 +2236,7 @@ class FluxComputeInterfaceConditionKernel : public FluxComputeKernel< NUM_EQN, N stdVector< real64 > saturations = {m_phaseVolFrac[seri[0]][sesri[0]][sei[0]][0], m_phaseVolFrac[seri[1]][sesri[1]][sei[1]][0] }; stdVector< real64 > pressures = {m_pres[seri[0]][sesri[0]][sei[0]], m_pres[seri[1]][sesri[1]][sei[1]] }; - bool isJfunction = 1; + bool isJfunction = 0; // loop over phases for( integer ip = 0; ip < m_numPhases; ++ip ) @@ -2318,9 +2309,9 @@ class FluxComputeInterfaceConditionKernel : public FluxComputeKernel< NUM_EQN, N if( m_hasCapPressure ) // check sign convention { real64 const capPres = m_phaseCapPressure[er][esr][ei][0][ip]; // Pc = Pc1 || Pc2 - jFMultiplier[ip][ke] = m_jFuncMultiplier[er][esr][ei][0]; + // jFMultiplier[ip][ke] = m_jFuncMultiplier[er][esr][ei][0]; - capPresIC[ip][ke] = capPres; + // capPresIC[ip][ke] = capPres; dCapGrad_dTrans -= signPotDiff[ke] * capPres; // dDPc/dT = (-Pc1 + Pc2) pot -= trans[ke] * capPres; // Phi = T P1 - rho T g z1 - T Pc1 || -T P2 + rho T g z2 + T // Pc2 @@ -2479,8 +2470,8 @@ class FluxComputeInterfaceConditionKernel : public FluxComputeKernel< NUM_EQN, N // this determines whether the local solver is needed becuase of heterogeneous capillary pressure regions - bool notOnInterface = std::fabs( jFMultiplier[0][0] - jFMultiplier[0][1] ) < 1 && std::fabs( jFMultiplier[1][0] - jFMultiplier[1][1] ) < 1; - notOnInterface = !connectorHasInterfaceConditionQ; + // bool notOnInterface = std::fabs( jFMultiplier[0][0] - jFMultiplier[0][1] ) < 1 && std::fabs( jFMultiplier[1][0] - jFMultiplier[1][1] ) < 1; + bool notOnInterface = !connectorHasInterfaceConditionQ; if( notOnInterface ) { for( integer ip = 0; ip < 2; ++ip ) @@ -2510,66 +2501,9 @@ class FluxComputeInterfaceConditionKernel : public FluxComputeKernel< NUM_EQN, N else { - // nonlinear solver's parameters - real64 tol = 1.0e-9; - int max_iter = 50; - bool converged = 0; - bool damping = true; - - // Local newton loop: - // Use of the capillary pressure kernel wrapper - StackArray< real64, 2, 2, immiscibleFlow::LAYOUT_PHASE > facePhaseVolFrac1( 1, 2 ); - StackArray< real64, 3, 2, constitutive::cappres::LAYOUT_CAPPRES > faceCapPres1( 1, 1, 2 ); - StackArray< real64, 4, 4, constitutive::cappres::LAYOUT_CAPPRES_DS > dfacePhaseVolFrac_dCapPres1( 1, 1, 2, 2 ); - StackArray< real64, 4, 4, constitutive::cappres::LAYOUT_CAPPRES_DS > dCapPres1_dfacePhaseVolFrac( 1, 1, 2, 2 ); - StackArray< real64, 2, 2, immiscibleFlow::LAYOUT_PHASE > facePhaseVolFrac2( 1, 2 ); - StackArray< real64, 3, 2, constitutive::cappres::LAYOUT_CAPPRES > faceCapPres2( 1, 1, 2 ); - StackArray< real64, 4, 4, constitutive::cappres::LAYOUT_CAPPRES_DS > dfacePhaseVolFrac_dCapPres2( 1, 1, 2, 2 ); - StackArray< real64, 4, 4, constitutive::cappres::LAYOUT_CAPPRES_DS > dCapPres2_dfacePhaseVolFrac( 1, 1, 2, 2 ); - StackArray< real64, 1, 2 > JFunc1( 2 ); - StackArray< real64, 1, 2 > JFunc2( 2 ); - JFunc1[0] = jFMultiplier[0][0]; - JFunc2[0] = jFMultiplier[0][1]; - - // finding endpoints: - facePhaseVolFrac1[0][1] = 0.0; - facePhaseVolFrac1[0][0] = 1.0; - m_capPressureWrapper.compute( facePhaseVolFrac1[0], - JFunc1.toSliceConst(), - faceCapPres1[0][0], - dCapPres1_dfacePhaseVolFrac[0][0] ); - real64 const Pc1_min = faceCapPres1[0][0][0]; - facePhaseVolFrac1[0][1] = 1.0; - facePhaseVolFrac1[0][0] = 0.0; - m_capPressureWrapper.compute( facePhaseVolFrac1[0], - JFunc1.toSliceConst(), - faceCapPres1[0][0], - dCapPres1_dfacePhaseVolFrac[0][0] ); - real64 const Pc1_max = faceCapPres1[0][0][0]; - - facePhaseVolFrac2[0][1] = 0.0; - facePhaseVolFrac2[0][0] = 1.0; - m_capPressureWrapper.compute( facePhaseVolFrac2[0], - JFunc2.toSliceConst(), - faceCapPres2[0][0], - dCapPres2_dfacePhaseVolFrac[0][0] ); - real64 const Pc2_min = faceCapPres2[0][0][0]; - facePhaseVolFrac2[0][1] = 1.0; - facePhaseVolFrac2[0][0] = 0.0; - m_capPressureWrapper.compute( facePhaseVolFrac2[0], - JFunc2.toSliceConst(), - faceCapPres2[0][0], - dCapPres2_dfacePhaseVolFrac[0][0] ); - real64 const Pc2_max = faceCapPres2[0][0][0]; + bool converged = 0; - // Use of the relative permeability kernel wrapper - StackArray< real64, 3, 2, constitutive::relperm::LAYOUT_RELPERM > faceTrappedVolFrac1( 1, 1, 2 ); - StackArray< real64, 3, 2, constitutive::relperm::LAYOUT_RELPERM > faceRelPerm1( 1, 1, 2 ); - StackArray< real64, 4, 4, constitutive::relperm::LAYOUT_RELPERM_DS > dfacePhaseRelPerm1_dPhaseVolFrac( 1, 1, 2, 2 ); - StackArray< real64, 3, 2, constitutive::relperm::LAYOUT_RELPERM > faceTrappedVolFrac2( 1, 1, 2 ); - StackArray< real64, 3, 2, constitutive::relperm::LAYOUT_RELPERM > faceRelPerm2( 1, 1, 2 ); - StackArray< real64, 4, 4, constitutive::relperm::LAYOUT_RELPERM_DS > dfacePhaseRelPerm2_dPhaseVolFrac( 1, 1, 2, 2 ); // clear working arrays real64 halfFluxVal[numEqn][2]{}; @@ -2580,31 +2514,9 @@ class FluxComputeInterfaceConditionKernel : public FluxComputeKernel< NUM_EQN, N real64 dhalfFlux_duT[numEqn][2]{}; real64 dhalfFlux_dpc[numEqn][2]{}; - // initial guess: - real64 S_int[numEqn]{}; - real64 const Pc1 = capPresIC[0][0]; - real64 const Pc2 = capPresIC[0][1]; - - real64 Pc_int = ( Pc1 + Pc2 ) / 2.0; - - real64 Pc_min_all = fmax( Pc1_min, Pc2_min ); - real64 Pc_max_all = fmin( Pc1_max, Pc2_max ); - - if( Pc_int < Pc_min_all || Pc_int > Pc_max_all ) - { - Pc_int = ( Pc_min_all + Pc_max_all ) / 2.0; - } - - real64 same_Pc_int = Pc_int; - // GEOS_UNUSED_VAR(gravCoef2[0]); - // GEOS_UNUSED_VAR(gravCoef2[1]); - - // Pc_int = fmin( Pc_max_all, fmax( Pc_int, Pc_min_all )); - // m_interfaceConstitutivePairs[0][0] = std::make_tuple( relPerm, capPressure, fluid ); -// m_interfaceConstitutivePairs[0][1] = std::make_tuple( relPerm, capPressure, fluid ); - - stdVector< real64 > JFMultipliers = {jFMultiplier[0][0], jFMultiplier[0][1]}; + // stdVector< real64 > JFMultipliers = {jFMultiplier[0][0], jFMultiplier[0][1]}; + stdVector< real64 > JFMultipliers = {0.0, 0.0}; stdVector< real64 > trappedSats1 = {0.0, 0.0}; stdVector< real64 > trappedSats2 = {0.0, 0.0}; stdVector< real64 > transHats = {transHat[0], transHat[1]}; @@ -2614,9 +2526,28 @@ class FluxComputeInterfaceConditionKernel : public FluxComputeKernel< NUM_EQN, N stdVector< real64 > cellCenterDuTdS = {duT_dP[0], duT_dP[1], duT_dS[0], duT_dS[1]}; stdVector< real64 > cellCenterDens = {density2[0], density2[1]}; stdVector< real64 > cellCenterDens_dP = {dDens_dP2[0][0], dDens_dP2[0][1], dDens_dP2[1][0], dDens_dP2[1][1]}; - std::vector< RelativePermeabilityBase * > relPerms = {std::get< 0 >( m_interfaceConstitutivePairs_temp ), std::get< 0 >( m_interfaceConstitutivePairs_temp )}; - std::vector< CapillaryPressureBase * > capPressures = {std::get< 1 >( m_interfaceConstitutivePairs_temp ), std::get< 1 >( m_interfaceConstitutivePairs_temp )}; - std::vector< TwoPhaseImmiscibleFluid * > fluids = {std::get< 2 >( m_interfaceConstitutivePairs_temp ), std::get< 2 >( m_interfaceConstitutivePairs_temp )}; + // std::vector< RelativePermeabilityBase * > relPerms = {std::get< 0 >( m_interfaceConstitutivePairs_temp ), std::get< 0 >( m_interfaceConstitutivePairs_temp )}; + // std::vector< CapillaryPressureBase * > capPressures = {std::get< 1 >( m_interfaceConstitutivePairs_temp ), std::get< 1 >( m_interfaceConstitutivePairs_temp )}; + // std::vector< TwoPhaseImmiscibleFluid * > fluids = {std::get< 2 >( m_interfaceConstitutivePairs_temp ), std::get< 2 >( m_interfaceConstitutivePairs_temp )}; + + // auto const & pairArray = m_interfaceConstitutivePairs[0]; + localIndex const surfaceRegionIndex = m_interfaceRegionByConnector.at(iconn); +auto const & pairArray = m_interfaceConstitutivePairs[surfaceRegionIndex]; + +std::vector< constitutive::RelativePermeabilityBase * > relPerms = { + std::get<0>( pairArray[0] ), + std::get<0>( pairArray[1] ) +}; + +std::vector< constitutive::CapillaryPressureBase * > capPressures = { + std::get<1>( pairArray[0] ), + std::get<1>( pairArray[1] ) +}; + +std::vector< constitutive::TwoPhaseImmiscibleFluid * > fluids = { + std::get<2>( pairArray[0] ), + std::get<2>( pairArray[1] ) +}; stdVector< real64 > phi = {halfFluxVal[0][0], halfFluxVal[0][1]}; stdVector< real64 > grad_phi_P = {0.0, 0.0, 0.0, 0.0}; @@ -2671,16 +2602,16 @@ class FluxComputeInterfaceConditionKernel : public FluxComputeKernel< NUM_EQN, N protected: /// Reference to the capillary pressure wrapper - CAPPRESWRAPPER const m_capPressureWrapper; - RELPERMWRAPPER const m_relPermWrapper; + // CAPPRESWRAPPER const m_capPressureWrapper; + // RELPERMWRAPPER const m_relPermWrapper; string_array const m_interfaceFaceSetNames; stdVector< std::array< std::tuple< constitutive::RelativePermeabilityBase *, constitutive::CapillaryPressureBase *, constitutive::TwoPhaseImmiscibleFluid * >, 2 > > const m_interfaceConstitutivePairs; unordered_map< localIndex, localIndex > const m_interfaceRegionByConnector; - std::tuple< constitutive::RelativePermeabilityBase *, - constitutive::CapillaryPressureBase *, - constitutive::TwoPhaseImmiscibleFluid * > const m_interfaceConstitutivePairs_temp; + // std::tuple< constitutive::RelativePermeabilityBase *, + // constitutive::CapillaryPressureBase *, + // constitutive::TwoPhaseImmiscibleFluid * > const m_interfaceConstitutivePairs_temp; }; @@ -2758,7 +2689,8 @@ class FluxComputeKernelFactory * @param[inout] localMatrix the local CRS matrix * @param[inout] localRhs the local right-hand side vector */ - template< typename POLICY, typename STENCILWRAPPER, typename CAPPRESWRAPPER, typename RELPERMWRAPPER > + // template< typename POLICY, typename STENCILWRAPPER, typename CAPPRESWRAPPER, typename RELPERMWRAPPER > + template< typename POLICY, typename STENCILWRAPPER > static void createAndLaunch( integer const numPhases, globalIndex const rankOffset, @@ -2769,16 +2701,16 @@ class FluxComputeKernelFactory string const & solverName, ElementRegionManager const & elemManager, STENCILWRAPPER const & stencilWrapper, - CAPPRESWRAPPER const & capPresWrapper, - RELPERMWRAPPER const & relPermWrapper, + // CAPPRESWRAPPER const & capPresWrapper, + // RELPERMWRAPPER const & relPermWrapper, string_array const & interfaceFaceSetNames, stdVector< std::array< std::tuple< constitutive::RelativePermeabilityBase *, constitutive::CapillaryPressureBase *, constitutive::TwoPhaseImmiscibleFluid * >, 2 > > const & interfaceConstitutivePairs, unordered_map< localIndex, localIndex > const & interfaceRegionByConnector, - std::tuple< constitutive::RelativePermeabilityBase *, - constitutive::CapillaryPressureBase *, - constitutive::TwoPhaseImmiscibleFluid * > const & interfaceConstitutivePairs_temp, + // std::tuple< constitutive::RelativePermeabilityBase *, + // constitutive::CapillaryPressureBase *, + // constitutive::TwoPhaseImmiscibleFluid * > const & interfaceConstitutivePairs_temp, ElementSubRegionBase const & subRegion, real64 const & dt, CRSMatrixView< real64, globalIndex const > const & localMatrix, @@ -2791,16 +2723,21 @@ class FluxComputeKernelFactory elemManager.constructArrayViewAccessor< globalIndex, 1 >( dofKey ); dofNumberAccessor.setName( solverName + "/accessors/" + dofKey ); - using kernelType = FluxComputeInterfaceConditionKernel< NUM_EQN, NUM_DOF, STENCILWRAPPER, CAPPRESWRAPPER, RELPERMWRAPPER >; + // using kernelType = FluxComputeInterfaceConditionKernel< NUM_EQN, NUM_DOF, STENCILWRAPPER, CAPPRESWRAPPER, RELPERMWRAPPER >; + using kernelType = FluxComputeInterfaceConditionKernel< NUM_EQN, NUM_DOF, STENCILWRAPPER >; typename kernelType::ImmiscibleMultiphaseFlowAccessors flowAccessors( elemManager, solverName ); typename kernelType::MultiphaseFluidAccessors fluidAccessors( elemManager, solverName ); typename kernelType::CapPressureAccessors capPressureAccessors( elemManager, solverName ); typename kernelType::PermeabilityAccessors permAccessors( elemManager, solverName ); - kernelType kernel( numPhases, rankOffset, stencilWrapper, capPresWrapper, relPermWrapper, dofNumberAccessor, + // kernelType kernel( numPhases, rankOffset, stencilWrapper, capPresWrapper, relPermWrapper, dofNumberAccessor, + // flowAccessors, fluidAccessors, capPressureAccessors, permAccessors, + // dt, localMatrix, localRhs, hasCapPressure, useTotalMassEquation, + // checkPhasePresenceInGravity, interfaceFaceSetNames, interfaceConstitutivePairs, interfaceRegionByConnector, interfaceConstitutivePairs_temp, domainSize ); + kernelType kernel( numPhases, rankOffset, stencilWrapper, dofNumberAccessor, flowAccessors, fluidAccessors, capPressureAccessors, permAccessors, dt, localMatrix, localRhs, hasCapPressure, useTotalMassEquation, - checkPhasePresenceInGravity, interfaceFaceSetNames, interfaceConstitutivePairs, interfaceRegionByConnector, interfaceConstitutivePairs_temp, domainSize ); + checkPhasePresenceInGravity, interfaceFaceSetNames, interfaceConstitutivePairs, interfaceRegionByConnector, domainSize ); kernelType::template launch< POLICY >( stencilWrapper.size(), kernel ); } }; From 98710589a15fb99617dca24f3b42e7865bfcd58b Mon Sep 17 00:00:00 2001 From: Ammara-14 Date: Wed, 4 Feb 2026 12:27:48 -0800 Subject: [PATCH 095/102] Adding input files and compiles on release --- .../initialPressure.txt | 0 .../1D_case/initialSaturation1.txt | 10 + .../1D_case/initialSaturation2.txt | 10 + .../jFunction_linear.txt | 0 .../1D_case/permx.geos | 10 + .../1D_case/permy.geos | 10 + .../1D_case/permz.geos | 10 + .../phaseVolumeFraction_water_linear.txt | 0 .../1D_case/tables/jFunction | 0 .../1D_case/tables/jFunction.txt | 76 ++ .../tables/jFunction_linear.txt | 0 .../tables/phaseVolumeFraction_water.txt | 2 +- .../phaseVolumeFraction_water_linear.txt | 0 .../uni_directional_flow_base.xml | 178 ++- ...i_directional_flow_interface_condition.xml | 30 +- .../1D_case/x.txt | 1 + .../1D_case/y.txt | 1 + .../1D_case/z.txt | 10 + .../3D_case/input/initialPressure.txt | 1200 +++++++++++++++++ .../3D_case/input/initialSaturation1.txt | 1200 +++++++++++++++++ .../3D_case/input/initialSaturation2.txt | 1200 +++++++++++++++++ .../3D_case/input/permx.geos | 1200 +++++++++++++++++ .../3D_case/input/permy.geos | 1200 +++++++++++++++++ .../3D_case/input/permz.geos | 1200 +++++++++++++++++ .../3D_case/input/x.txt | 10 + .../3D_case/input/y.txt | 6 + .../3D_case/input/z.txt | 20 + .../3D_case/uni_directional_flow_base.xml | 293 ++++ ...i_directional_flow_interface_condition.xml | 66 + ...oPhase_GravitySegregation_1d_pc_heter2.xml | 280 ---- .../initialSaturation1.txt | 10 - .../initialSaturation2.txt | 10 - .../permx.geos | 10 - .../permy.geos | 10 - .../permz.geos | 10 - .../tables/jFunction.txt | 13 - .../tables/phaseVolumeFraction_water.txt | 13 - .../x.txt | 1 - .../y.txt | 1 - .../z.txt | 10 - .../tables/jFunction_linear.txt | 2 - .../phaseVolumeFraction_water_linear.txt | 2 - .../BrooksCoreyCapillaryPressure.hpp | 2 + .../JFunctionCapillaryPressure.hpp | 1 + .../TableCapillaryPressure.hpp | 2 + .../fluidFlow/ImmiscibleMultiphaseFlow.cpp | 4 +- .../ImmiscibleMultiphaseKernels.hpp | 32 +- 47 files changed, 7895 insertions(+), 461 deletions(-) rename inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/{immiscible_GS_1d_pc_heter_famousCase_withIC => 1D_case}/initialPressure.txt (100%) create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/initialSaturation1.txt create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/initialSaturation2.txt rename inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/{immiscible_GS_1d_pc_heter_famousCase_withIC => 1D_case}/jFunction_linear.txt (100%) create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/permx.geos create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/permy.geos create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/permz.geos rename inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/{immiscible_GS_1d_pc_heter_famousCase_withIC => 1D_case}/phaseVolumeFraction_water_linear.txt (100%) create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/tables/jFunction create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/tables/jFunction.txt rename inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/{immiscible_GS_1d_pc_heter_famousCase_withIC => 1D_case}/tables/jFunction_linear.txt (100%) rename inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/{ => 1D_case}/tables/phaseVolumeFraction_water.txt (99%) mode change 100755 => 100644 rename inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/{immiscible_GS_1d_pc_heter_famousCase_withIC => 1D_case}/tables/phaseVolumeFraction_water_linear.txt (100%) rename inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/{ => 1D_case}/uni_directional_flow_base.xml (55%) rename inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/{ => 1D_case}/uni_directional_flow_interface_condition.xml (71%) create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/x.txt create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/y.txt create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/z.txt create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/initialPressure.txt create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/initialSaturation1.txt create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/initialSaturation2.txt create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/permx.geos create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/permy.geos create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/permz.geos create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/x.txt create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/y.txt create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/z.txt create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/uni_directional_flow_base.xml create mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/uni_directional_flow_interface_condition.xml delete mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/immiscibleTwoPhase_GravitySegregation_1d_pc_heter2.xml delete mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/initialSaturation1.txt delete mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/initialSaturation2.txt delete mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/permx.geos delete mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/permy.geos delete mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/permz.geos delete mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/tables/jFunction.txt delete mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/tables/phaseVolumeFraction_water.txt delete mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/x.txt delete mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/y.txt delete mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/z.txt delete mode 100644 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/tables/jFunction_linear.txt delete mode 100755 inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/tables/phaseVolumeFraction_water_linear.txt diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/initialPressure.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/initialPressure.txt similarity index 100% rename from inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/initialPressure.txt rename to inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/initialPressure.txt diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/initialSaturation1.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/initialSaturation1.txt new file mode 100644 index 00000000000..1859fabae78 --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/initialSaturation1.txt @@ -0,0 +1,10 @@ +0.95 +0.95 +0.95 +0.95 +0.95 +0.95 +0.95 +0.05 +0.05 +0.05 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/initialSaturation2.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/initialSaturation2.txt new file mode 100644 index 00000000000..d113536f2fd --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/initialSaturation2.txt @@ -0,0 +1,10 @@ +0.05 +0.05 +0.05 +0.05 +0.05 +0.05 +0.05 +0.95 +0.95 +0.95 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/jFunction_linear.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/jFunction_linear.txt similarity index 100% rename from inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/jFunction_linear.txt rename to inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/jFunction_linear.txt diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/permx.geos b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/permx.geos new file mode 100644 index 00000000000..4d47d8fa568 --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/permx.geos @@ -0,0 +1,10 @@ +50 +50 +50 +50 +50 +200 +200 +200 +200 +200 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/permy.geos b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/permy.geos new file mode 100644 index 00000000000..4d47d8fa568 --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/permy.geos @@ -0,0 +1,10 @@ +50 +50 +50 +50 +50 +200 +200 +200 +200 +200 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/permz.geos b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/permz.geos new file mode 100644 index 00000000000..4d47d8fa568 --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/permz.geos @@ -0,0 +1,10 @@ +50 +50 +50 +50 +50 +200 +200 +200 +200 +200 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/phaseVolumeFraction_water_linear.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/phaseVolumeFraction_water_linear.txt similarity index 100% rename from inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/phaseVolumeFraction_water_linear.txt rename to inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/phaseVolumeFraction_water_linear.txt diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/tables/jFunction b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/tables/jFunction new file mode 100644 index 00000000000..e69de29bb2d diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/tables/jFunction.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/tables/jFunction.txt new file mode 100644 index 00000000000..72a78a75b85 --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/tables/jFunction.txt @@ -0,0 +1,76 @@ +99.9980934 +17.78445609 +11.20350909 +8.549878542 +7.057769576 +6.082201546 +5.386086427 +4.86006559 +4.446116454 +4.110353325 +3.831547061 +3.595663494 +3.393021946 +3.216710174 +3.061649542 +2.924017691 +2.800877928 +2.68993357 +2.589360389 +2.497689435 +2.413723433 +2.336475912 +2.265126101 +2.198985069 +2.137469915 +2.080083807 +2.02640045 +1.976051821 +1.928718377 +1.884121218 +1.842015737 +1.802186411 +1.764442543 +1.728614745 +1.694551981 +1.662119113 +1.631194842 +1.601669938 +1.573445757 +1.546432977 +1.520550493 +1.495724483 +1.471887601 +1.448978263 +1.426940034 +1.405721104 +1.385273798 +1.365554178 +1.346521677 +1.328138769 +1.310370692 +1.293185194 +1.276552299 +1.260444114 +1.244834648 +1.229699646 +1.215016445 +1.200763848 +1.186921998 +1.173472275 +1.160397205 +1.147680364 +1.135306301 +1.123260469 +1.111529155 +1.100099423 +1.088959056 +1.078096509 +1.067500858 +1.057161765 +1.047069433 +1.03721457 +1.027588362 +1.018182437 +1.008988837 +0.999999998 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/tables/jFunction_linear.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/tables/jFunction_linear.txt similarity index 100% rename from inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/tables/jFunction_linear.txt rename to inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/tables/jFunction_linear.txt diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/tables/phaseVolumeFraction_water.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/tables/phaseVolumeFraction_water.txt old mode 100755 new mode 100644 similarity index 99% rename from inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/tables/phaseVolumeFraction_water.txt rename to inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/tables/phaseVolumeFraction_water.txt index 30a57a9dee4..f38627d4e85 --- a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/tables/phaseVolumeFraction_water.txt +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/tables/phaseVolumeFraction_water.txt @@ -1,4 +1,4 @@ -0 +0.001 0.013333333 0.026666667 0.04 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/tables/phaseVolumeFraction_water_linear.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/tables/phaseVolumeFraction_water_linear.txt similarity index 100% rename from inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/tables/phaseVolumeFraction_water_linear.txt rename to inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/tables/phaseVolumeFraction_water_linear.txt diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/uni_directional_flow_base.xml b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/uni_directional_flow_base.xml similarity index 55% rename from inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/uni_directional_flow_base.xml rename to inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/uni_directional_flow_base.xml index 2640edbdc80..efbd5b34421 100644 --- a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/uni_directional_flow_base.xml +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/uni_directional_flow_base.xml @@ -2,19 +2,21 @@ - + + newtonTol="1.0e-5" + newtonMaxIter="20" + maxTimeStepCuts="20" + maxSubSteps="2000"/> + values="{ 900 }" /> + values="{ 400 }" /> + values="{ 0.001 }" /> + values="{ 0.001 }" /> + + + + coordinateFiles="{ tables/phaseVolumeFraction_water.txt }" + voxelFile="tables/jFunction.txt"/> + + + + @@ -88,51 +127,67 @@ + permeabilityComponents="{ 1.0e-14, 1.0e-14, 1.0e-14}"/> - - + wettingNonWettingSurfaceTension="6.12e-3" + permeabilityDirection="XY"/> --> + + + + + @@ -141,61 +196,73 @@ + + + scale="1.0" + functionName="pressureTable" /> + scale="1.0" + functionName="saturationTable1" /> + scale="1.0" + functionName="saturationTable2" /> - - - + fieldName="rockPerm_permeability" + functionName="permxFunc" + scale="1.0e-14"/> + fieldName="rockPerm_permeability" + functionName="permyFunc" + scale="1.0e-14"/> + fieldName="rockPerm_permeability" + functionName="permzFunc" + scale="1.0e-14"/> + @@ -203,23 +270,24 @@ - + - + diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/uni_directional_flow_interface_condition.xml b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/uni_directional_flow_interface_condition.xml similarity index 71% rename from inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/uni_directional_flow_interface_condition.xml rename to inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/uni_directional_flow_interface_condition.xml index c263012d27c..41ba4e3ed92 100644 --- a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/uni_directional_flow_interface_condition.xml +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/uni_directional_flow_interface_condition.xml @@ -10,42 +10,42 @@ - + xMax="{0.01, 1.00001, 1.00001}"/> --> + xMin="{ -0.00001, -0.00001, -0.00001}" + xMax="{ 1.00001, 1.00001, 1.00001}"/> + xMin="{ -0.01, -0.01, 4.99 }" + xMax="{ 1.01, 1.01, 5.01 }"/> + maxTime="86.4e+05"> - + diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/x.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/x.txt new file mode 100644 index 00000000000..2eb3c4fe4ee --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/x.txt @@ -0,0 +1 @@ +0.5 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/y.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/y.txt new file mode 100644 index 00000000000..2eb3c4fe4ee --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/y.txt @@ -0,0 +1 @@ +0.5 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/z.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/z.txt new file mode 100644 index 00000000000..f43a1f14d26 --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/z.txt @@ -0,0 +1,10 @@ +0.5 +1.5 +2.5 +3.5 +4.5 +5.5 +6.5 +7.5 +8.5 +9.5 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/initialPressure.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/initialPressure.txt new file mode 100644 index 00000000000..6963bb6148c --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/initialPressure.txt @@ -0,0 +1,1200 @@ +1.00022072e+07 +1.00022072e+07 +1.00022072e+07 +1.00022072e+07 +1.00022072e+07 +1.00022072e+07 +1.00022072e+07 +1.00022072e+07 +1.00022072e+07 +1.00022072e+07 +1.00022072e+07 +1.00022072e+07 +1.00022072e+07 +1.00022072e+07 +1.00022072e+07 +1.00022072e+07 +1.00022072e+07 +1.00022072e+07 +1.00022072e+07 +1.00022072e+07 +1.00022072e+07 +1.00022072e+07 +1.00022072e+07 +1.00022072e+07 +1.00022072e+07 +1.00022072e+07 +1.00022072e+07 +1.00022072e+07 +1.00022072e+07 +1.00022072e+07 +1.00022072e+07 +1.00022072e+07 +1.00022072e+07 +1.00022072e+07 +1.00022072e+07 +1.00022072e+07 +1.00022072e+07 +1.00022072e+07 +1.00022072e+07 +1.00022072e+07 +1.00022072e+07 +1.00022072e+07 +1.00022072e+07 +1.00022072e+07 +1.00022072e+07 +1.00022072e+07 +1.00022072e+07 +1.00022072e+07 +1.00022072e+07 +1.00022072e+07 +1.00022072e+07 +1.00022072e+07 +1.00022072e+07 +1.00022072e+07 +1.00022072e+07 +1.00022072e+07 +1.00022072e+07 +1.00022072e+07 +1.00022072e+07 +1.00022072e+07 +1.00066218e+07 +1.00066218e+07 +1.00066218e+07 +1.00066218e+07 +1.00066218e+07 +1.00066218e+07 +1.00066218e+07 +1.00066218e+07 +1.00066218e+07 +1.00066218e+07 +1.00066218e+07 +1.00066218e+07 +1.00066218e+07 +1.00066218e+07 +1.00066218e+07 +1.00066218e+07 +1.00066218e+07 +1.00066218e+07 +1.00066218e+07 +1.00066218e+07 +1.00066218e+07 +1.00066218e+07 +1.00066218e+07 +1.00066218e+07 +1.00066218e+07 +1.00066218e+07 +1.00066218e+07 +1.00066218e+07 +1.00066218e+07 +1.00066218e+07 +1.00066218e+07 +1.00066218e+07 +1.00066218e+07 +1.00066218e+07 +1.00066218e+07 +1.00066218e+07 +1.00066218e+07 +1.00066218e+07 +1.00066218e+07 +1.00066218e+07 +1.00066218e+07 +1.00066218e+07 +1.00066218e+07 +1.00066218e+07 +1.00066218e+07 +1.00066218e+07 +1.00066218e+07 +1.00066218e+07 +1.00066218e+07 +1.00066218e+07 +1.00066218e+07 +1.00066218e+07 +1.00066218e+07 +1.00066218e+07 +1.00066218e+07 +1.00066218e+07 +1.00066218e+07 +1.00066218e+07 +1.00066218e+07 +1.00066218e+07 +1.00110362e+07 +1.00110362e+07 +1.00110362e+07 +1.00110362e+07 +1.00110362e+07 +1.00110362e+07 +1.00110362e+07 +1.00110362e+07 +1.00110362e+07 +1.00110362e+07 +1.00110362e+07 +1.00110362e+07 +1.00110362e+07 +1.00110362e+07 +1.00110362e+07 +1.00110362e+07 +1.00110362e+07 +1.00110362e+07 +1.00110362e+07 +1.00110362e+07 +1.00110362e+07 +1.00110362e+07 +1.00110362e+07 +1.00110362e+07 +1.00110362e+07 +1.00110362e+07 +1.00110362e+07 +1.00110362e+07 +1.00110362e+07 +1.00110362e+07 +1.00110362e+07 +1.00110362e+07 +1.00110362e+07 +1.00110362e+07 +1.00110362e+07 +1.00110362e+07 +1.00110362e+07 +1.00110362e+07 +1.00110362e+07 +1.00110362e+07 +1.00110362e+07 +1.00110362e+07 +1.00110362e+07 +1.00110362e+07 +1.00110362e+07 +1.00110362e+07 +1.00110362e+07 +1.00110362e+07 +1.00110362e+07 +1.00110362e+07 +1.00110362e+07 +1.00110362e+07 +1.00110362e+07 +1.00110362e+07 +1.00110362e+07 +1.00110362e+07 +1.00110362e+07 +1.00110362e+07 +1.00110362e+07 +1.00110362e+07 +1.00154508e+07 +1.00154508e+07 +1.00154508e+07 +1.00154508e+07 +1.00154508e+07 +1.00154508e+07 +1.00154508e+07 +1.00154508e+07 +1.00154508e+07 +1.00154508e+07 +1.00154508e+07 +1.00154508e+07 +1.00154508e+07 +1.00154508e+07 +1.00154508e+07 +1.00154508e+07 +1.00154508e+07 +1.00154508e+07 +1.00154508e+07 +1.00154508e+07 +1.00154508e+07 +1.00154508e+07 +1.00154508e+07 +1.00154508e+07 +1.00154508e+07 +1.00154508e+07 +1.00154508e+07 +1.00154508e+07 +1.00154508e+07 +1.00154508e+07 +1.00154508e+07 +1.00154508e+07 +1.00154508e+07 +1.00154508e+07 +1.00154508e+07 +1.00154508e+07 +1.00154508e+07 +1.00154508e+07 +1.00154508e+07 +1.00154508e+07 +1.00154508e+07 +1.00154508e+07 +1.00154508e+07 +1.00154508e+07 +1.00154508e+07 +1.00154508e+07 +1.00154508e+07 +1.00154508e+07 +1.00154508e+07 +1.00154508e+07 +1.00154508e+07 +1.00154508e+07 +1.00154508e+07 +1.00154508e+07 +1.00154508e+07 +1.00154508e+07 +1.00154508e+07 +1.00154508e+07 +1.00154508e+07 +1.00154508e+07 +1.00198652e+07 +1.00198652e+07 +1.00198652e+07 +1.00198652e+07 +1.00198652e+07 +1.00198652e+07 +1.00198652e+07 +1.00198652e+07 +1.00198652e+07 +1.00198652e+07 +1.00198652e+07 +1.00198652e+07 +1.00198652e+07 +1.00198652e+07 +1.00198652e+07 +1.00198652e+07 +1.00198652e+07 +1.00198652e+07 +1.00198652e+07 +1.00198652e+07 +1.00198652e+07 +1.00198652e+07 +1.00198652e+07 +1.00198652e+07 +1.00198652e+07 +1.00198652e+07 +1.00198652e+07 +1.00198652e+07 +1.00198652e+07 +1.00198652e+07 +1.00198652e+07 +1.00198652e+07 +1.00198652e+07 +1.00198652e+07 +1.00198652e+07 +1.00198652e+07 +1.00198652e+07 +1.00198652e+07 +1.00198652e+07 +1.00198652e+07 +1.00198652e+07 +1.00198652e+07 +1.00198652e+07 +1.00198652e+07 +1.00198652e+07 +1.00198652e+07 +1.00198652e+07 +1.00198652e+07 +1.00198652e+07 +1.00198652e+07 +1.00198652e+07 +1.00198652e+07 +1.00198652e+07 +1.00198652e+07 +1.00198652e+07 +1.00198652e+07 +1.00198652e+07 +1.00198652e+07 +1.00198652e+07 +1.00198652e+07 +1.00242798e+07 +1.00242798e+07 +1.00242798e+07 +1.00242798e+07 +1.00242798e+07 +1.00242798e+07 +1.00242798e+07 +1.00242798e+07 +1.00242798e+07 +1.00242798e+07 +1.00242798e+07 +1.00242798e+07 +1.00242798e+07 +1.00242798e+07 +1.00242798e+07 +1.00242798e+07 +1.00242798e+07 +1.00242798e+07 +1.00242798e+07 +1.00242798e+07 +1.00242798e+07 +1.00242798e+07 +1.00242798e+07 +1.00242798e+07 +1.00242798e+07 +1.00242798e+07 +1.00242798e+07 +1.00242798e+07 +1.00242798e+07 +1.00242798e+07 +1.00242798e+07 +1.00242798e+07 +1.00242798e+07 +1.00242798e+07 +1.00242798e+07 +1.00242798e+07 +1.00242798e+07 +1.00242798e+07 +1.00242798e+07 +1.00242798e+07 +1.00242798e+07 +1.00242798e+07 +1.00242798e+07 +1.00242798e+07 +1.00242798e+07 +1.00242798e+07 +1.00242798e+07 +1.00242798e+07 +1.00242798e+07 +1.00242798e+07 +1.00242798e+07 +1.00242798e+07 +1.00242798e+07 +1.00242798e+07 +1.00242798e+07 +1.00242798e+07 +1.00242798e+07 +1.00242798e+07 +1.00242798e+07 +1.00242798e+07 +1.00286942e+07 +1.00286942e+07 +1.00286942e+07 +1.00286942e+07 +1.00286942e+07 +1.00286942e+07 +1.00286942e+07 +1.00286942e+07 +1.00286942e+07 +1.00286942e+07 +1.00286942e+07 +1.00286942e+07 +1.00286942e+07 +1.00286942e+07 +1.00286942e+07 +1.00286942e+07 +1.00286942e+07 +1.00286942e+07 +1.00286942e+07 +1.00286942e+07 +1.00286942e+07 +1.00286942e+07 +1.00286942e+07 +1.00286942e+07 +1.00286942e+07 +1.00286942e+07 +1.00286942e+07 +1.00286942e+07 +1.00286942e+07 +1.00286942e+07 +1.00286942e+07 +1.00286942e+07 +1.00286942e+07 +1.00286942e+07 +1.00286942e+07 +1.00286942e+07 +1.00286942e+07 +1.00286942e+07 +1.00286942e+07 +1.00286942e+07 +1.00286942e+07 +1.00286942e+07 +1.00286942e+07 +1.00286942e+07 +1.00286942e+07 +1.00286942e+07 +1.00286942e+07 +1.00286942e+07 +1.00286942e+07 +1.00286942e+07 +1.00286942e+07 +1.00286942e+07 +1.00286942e+07 +1.00286942e+07 +1.00286942e+07 +1.00286942e+07 +1.00286942e+07 +1.00286942e+07 +1.00286942e+07 +1.00286942e+07 +1.00331088e+07 +1.00331088e+07 +1.00331088e+07 +1.00331088e+07 +1.00331088e+07 +1.00331088e+07 +1.00331088e+07 +1.00331088e+07 +1.00331088e+07 +1.00331088e+07 +1.00331088e+07 +1.00331088e+07 +1.00331088e+07 +1.00331088e+07 +1.00331088e+07 +1.00331088e+07 +1.00331088e+07 +1.00331088e+07 +1.00331088e+07 +1.00331088e+07 +1.00331088e+07 +1.00331088e+07 +1.00331088e+07 +1.00331088e+07 +1.00331088e+07 +1.00331088e+07 +1.00331088e+07 +1.00331088e+07 +1.00331088e+07 +1.00331088e+07 +1.00331088e+07 +1.00331088e+07 +1.00331088e+07 +1.00331088e+07 +1.00331088e+07 +1.00331088e+07 +1.00331088e+07 +1.00331088e+07 +1.00331088e+07 +1.00331088e+07 +1.00331088e+07 +1.00331088e+07 +1.00331088e+07 +1.00331088e+07 +1.00331088e+07 +1.00331088e+07 +1.00331088e+07 +1.00331088e+07 +1.00331088e+07 +1.00331088e+07 +1.00331088e+07 +1.00331088e+07 +1.00331088e+07 +1.00331088e+07 +1.00331088e+07 +1.00331088e+07 +1.00331088e+07 +1.00331088e+07 +1.00331088e+07 +1.00331088e+07 +1.00375232e+07 +1.00375232e+07 +1.00375232e+07 +1.00375232e+07 +1.00375232e+07 +1.00375232e+07 +1.00375232e+07 +1.00375232e+07 +1.00375232e+07 +1.00375232e+07 +1.00375232e+07 +1.00375232e+07 +1.00375232e+07 +1.00375232e+07 +1.00375232e+07 +1.00375232e+07 +1.00375232e+07 +1.00375232e+07 +1.00375232e+07 +1.00375232e+07 +1.00375232e+07 +1.00375232e+07 +1.00375232e+07 +1.00375232e+07 +1.00375232e+07 +1.00375232e+07 +1.00375232e+07 +1.00375232e+07 +1.00375232e+07 +1.00375232e+07 +1.00375232e+07 +1.00375232e+07 +1.00375232e+07 +1.00375232e+07 +1.00375232e+07 +1.00375232e+07 +1.00375232e+07 +1.00375232e+07 +1.00375232e+07 +1.00375232e+07 +1.00375232e+07 +1.00375232e+07 +1.00375232e+07 +1.00375232e+07 +1.00375232e+07 +1.00375232e+07 +1.00375232e+07 +1.00375232e+07 +1.00375232e+07 +1.00375232e+07 +1.00375232e+07 +1.00375232e+07 +1.00375232e+07 +1.00375232e+07 +1.00375232e+07 +1.00375232e+07 +1.00375232e+07 +1.00375232e+07 +1.00375232e+07 +1.00375232e+07 +1.00419378e+07 +1.00419378e+07 +1.00419378e+07 +1.00419378e+07 +1.00419378e+07 +1.00419378e+07 +1.00419378e+07 +1.00419378e+07 +1.00419378e+07 +1.00419378e+07 +1.00419378e+07 +1.00419378e+07 +1.00419378e+07 +1.00419378e+07 +1.00419378e+07 +1.00419378e+07 +1.00419378e+07 +1.00419378e+07 +1.00419378e+07 +1.00419378e+07 +1.00419378e+07 +1.00419378e+07 +1.00419378e+07 +1.00419378e+07 +1.00419378e+07 +1.00419378e+07 +1.00419378e+07 +1.00419378e+07 +1.00419378e+07 +1.00419378e+07 +1.00419378e+07 +1.00419378e+07 +1.00419378e+07 +1.00419378e+07 +1.00419378e+07 +1.00419378e+07 +1.00419378e+07 +1.00419378e+07 +1.00419378e+07 +1.00419378e+07 +1.00419378e+07 +1.00419378e+07 +1.00419378e+07 +1.00419378e+07 +1.00419378e+07 +1.00419378e+07 +1.00419378e+07 +1.00419378e+07 +1.00419378e+07 +1.00419378e+07 +1.00419378e+07 +1.00419378e+07 +1.00419378e+07 +1.00419378e+07 +1.00419378e+07 +1.00419378e+07 +1.00419378e+07 +1.00419378e+07 +1.00419378e+07 +1.00419378e+07 +1.00463522e+07 +1.00463522e+07 +1.00463522e+07 +1.00463522e+07 +1.00463522e+07 +1.00463522e+07 +1.00463522e+07 +1.00463522e+07 +1.00463522e+07 +1.00463522e+07 +1.00463522e+07 +1.00463522e+07 +1.00463522e+07 +1.00463522e+07 +1.00463522e+07 +1.00463522e+07 +1.00463522e+07 +1.00463522e+07 +1.00463522e+07 +1.00463522e+07 +1.00463522e+07 +1.00463522e+07 +1.00463522e+07 +1.00463522e+07 +1.00463522e+07 +1.00463522e+07 +1.00463522e+07 +1.00463522e+07 +1.00463522e+07 +1.00463522e+07 +1.00463522e+07 +1.00463522e+07 +1.00463522e+07 +1.00463522e+07 +1.00463522e+07 +1.00463522e+07 +1.00463522e+07 +1.00463522e+07 +1.00463522e+07 +1.00463522e+07 +1.00463522e+07 +1.00463522e+07 +1.00463522e+07 +1.00463522e+07 +1.00463522e+07 +1.00463522e+07 +1.00463522e+07 +1.00463522e+07 +1.00463522e+07 +1.00463522e+07 +1.00463522e+07 +1.00463522e+07 +1.00463522e+07 +1.00463522e+07 +1.00463522e+07 +1.00463522e+07 +1.00463522e+07 +1.00463522e+07 +1.00463522e+07 +1.00463522e+07 +1.00507668e+07 +1.00507668e+07 +1.00507668e+07 +1.00507668e+07 +1.00507668e+07 +1.00507668e+07 +1.00507668e+07 +1.00507668e+07 +1.00507668e+07 +1.00507668e+07 +1.00507668e+07 +1.00507668e+07 +1.00507668e+07 +1.00507668e+07 +1.00507668e+07 +1.00507668e+07 +1.00507668e+07 +1.00507668e+07 +1.00507668e+07 +1.00507668e+07 +1.00507668e+07 +1.00507668e+07 +1.00507668e+07 +1.00507668e+07 +1.00507668e+07 +1.00507668e+07 +1.00507668e+07 +1.00507668e+07 +1.00507668e+07 +1.00507668e+07 +1.00507668e+07 +1.00507668e+07 +1.00507668e+07 +1.00507668e+07 +1.00507668e+07 +1.00507668e+07 +1.00507668e+07 +1.00507668e+07 +1.00507668e+07 +1.00507668e+07 +1.00507668e+07 +1.00507668e+07 +1.00507668e+07 +1.00507668e+07 +1.00507668e+07 +1.00507668e+07 +1.00507668e+07 +1.00507668e+07 +1.00507668e+07 +1.00507668e+07 +1.00507668e+07 +1.00507668e+07 +1.00507668e+07 +1.00507668e+07 +1.00507668e+07 +1.00507668e+07 +1.00507668e+07 +1.00507668e+07 +1.00507668e+07 +1.00507668e+07 +1.00551812e+07 +1.00551812e+07 +1.00551812e+07 +1.00551812e+07 +1.00551812e+07 +1.00551812e+07 +1.00551812e+07 +1.00551812e+07 +1.00551812e+07 +1.00551812e+07 +1.00551812e+07 +1.00551812e+07 +1.00551812e+07 +1.00551812e+07 +1.00551812e+07 +1.00551812e+07 +1.00551812e+07 +1.00551812e+07 +1.00551812e+07 +1.00551812e+07 +1.00551812e+07 +1.00551812e+07 +1.00551812e+07 +1.00551812e+07 +1.00551812e+07 +1.00551812e+07 +1.00551812e+07 +1.00551812e+07 +1.00551812e+07 +1.00551812e+07 +1.00551812e+07 +1.00551812e+07 +1.00551812e+07 +1.00551812e+07 +1.00551812e+07 +1.00551812e+07 +1.00551812e+07 +1.00551812e+07 +1.00551812e+07 +1.00551812e+07 +1.00551812e+07 +1.00551812e+07 +1.00551812e+07 +1.00551812e+07 +1.00551812e+07 +1.00551812e+07 +1.00551812e+07 +1.00551812e+07 +1.00551812e+07 +1.00551812e+07 +1.00551812e+07 +1.00551812e+07 +1.00551812e+07 +1.00551812e+07 +1.00551812e+07 +1.00551812e+07 +1.00551812e+07 +1.00551812e+07 +1.00551812e+07 +1.00551812e+07 +1.00595958e+07 +1.00595958e+07 +1.00595958e+07 +1.00595958e+07 +1.00595958e+07 +1.00595958e+07 +1.00595958e+07 +1.00595958e+07 +1.00595958e+07 +1.00595958e+07 +1.00595958e+07 +1.00595958e+07 +1.00595958e+07 +1.00595958e+07 +1.00595958e+07 +1.00595958e+07 +1.00595958e+07 +1.00595958e+07 +1.00595958e+07 +1.00595958e+07 +1.00595958e+07 +1.00595958e+07 +1.00595958e+07 +1.00595958e+07 +1.00595958e+07 +1.00595958e+07 +1.00595958e+07 +1.00595958e+07 +1.00595958e+07 +1.00595958e+07 +1.00595958e+07 +1.00595958e+07 +1.00595958e+07 +1.00595958e+07 +1.00595958e+07 +1.00595958e+07 +1.00595958e+07 +1.00595958e+07 +1.00595958e+07 +1.00595958e+07 +1.00595958e+07 +1.00595958e+07 +1.00595958e+07 +1.00595958e+07 +1.00595958e+07 +1.00595958e+07 +1.00595958e+07 +1.00595958e+07 +1.00595958e+07 +1.00595958e+07 +1.00595958e+07 +1.00595958e+07 +1.00595958e+07 +1.00595958e+07 +1.00595958e+07 +1.00595958e+07 +1.00595958e+07 +1.00595958e+07 +1.00595958e+07 +1.00595958e+07 +1.00640102e+07 +1.00640102e+07 +1.00640102e+07 +1.00640102e+07 +1.00640102e+07 +1.00640102e+07 +1.00640102e+07 +1.00640102e+07 +1.00640102e+07 +1.00640102e+07 +1.00640102e+07 +1.00640102e+07 +1.00640102e+07 +1.00640102e+07 +1.00640102e+07 +1.00640102e+07 +1.00640102e+07 +1.00640102e+07 +1.00640102e+07 +1.00640102e+07 +1.00640102e+07 +1.00640102e+07 +1.00640102e+07 +1.00640102e+07 +1.00640102e+07 +1.00640102e+07 +1.00640102e+07 +1.00640102e+07 +1.00640102e+07 +1.00640102e+07 +1.00640102e+07 +1.00640102e+07 +1.00640102e+07 +1.00640102e+07 +1.00640102e+07 +1.00640102e+07 +1.00640102e+07 +1.00640102e+07 +1.00640102e+07 +1.00640102e+07 +1.00640102e+07 +1.00640102e+07 +1.00640102e+07 +1.00640102e+07 +1.00640102e+07 +1.00640102e+07 +1.00640102e+07 +1.00640102e+07 +1.00640102e+07 +1.00640102e+07 +1.00640102e+07 +1.00640102e+07 +1.00640102e+07 +1.00640102e+07 +1.00640102e+07 +1.00640102e+07 +1.00640102e+07 +1.00640102e+07 +1.00640102e+07 +1.00640102e+07 +1.00684248e+07 +1.00684248e+07 +1.00684248e+07 +1.00684248e+07 +1.00684248e+07 +1.00684248e+07 +1.00684248e+07 +1.00684248e+07 +1.00684248e+07 +1.00684248e+07 +1.00684248e+07 +1.00684248e+07 +1.00684248e+07 +1.00684248e+07 +1.00684248e+07 +1.00684248e+07 +1.00684248e+07 +1.00684248e+07 +1.00684248e+07 +1.00684248e+07 +1.00684248e+07 +1.00684248e+07 +1.00684248e+07 +1.00684248e+07 +1.00684248e+07 +1.00684248e+07 +1.00684248e+07 +1.00684248e+07 +1.00684248e+07 +1.00684248e+07 +1.00684248e+07 +1.00684248e+07 +1.00684248e+07 +1.00684248e+07 +1.00684248e+07 +1.00684248e+07 +1.00684248e+07 +1.00684248e+07 +1.00684248e+07 +1.00684248e+07 +1.00684248e+07 +1.00684248e+07 +1.00684248e+07 +1.00684248e+07 +1.00684248e+07 +1.00684248e+07 +1.00684248e+07 +1.00684248e+07 +1.00684248e+07 +1.00684248e+07 +1.00684248e+07 +1.00684248e+07 +1.00684248e+07 +1.00684248e+07 +1.00684248e+07 +1.00684248e+07 +1.00684248e+07 +1.00684248e+07 +1.00684248e+07 +1.00684248e+07 +1.00728392e+07 +1.00728392e+07 +1.00728392e+07 +1.00728392e+07 +1.00728392e+07 +1.00728392e+07 +1.00728392e+07 +1.00728392e+07 +1.00728392e+07 +1.00728392e+07 +1.00728392e+07 +1.00728392e+07 +1.00728392e+07 +1.00728392e+07 +1.00728392e+07 +1.00728392e+07 +1.00728392e+07 +1.00728392e+07 +1.00728392e+07 +1.00728392e+07 +1.00728392e+07 +1.00728392e+07 +1.00728392e+07 +1.00728392e+07 +1.00728392e+07 +1.00728392e+07 +1.00728392e+07 +1.00728392e+07 +1.00728392e+07 +1.00728392e+07 +1.00728392e+07 +1.00728392e+07 +1.00728392e+07 +1.00728392e+07 +1.00728392e+07 +1.00728392e+07 +1.00728392e+07 +1.00728392e+07 +1.00728392e+07 +1.00728392e+07 +1.00728392e+07 +1.00728392e+07 +1.00728392e+07 +1.00728392e+07 +1.00728392e+07 +1.00728392e+07 +1.00728392e+07 +1.00728392e+07 +1.00728392e+07 +1.00728392e+07 +1.00728392e+07 +1.00728392e+07 +1.00728392e+07 +1.00728392e+07 +1.00728392e+07 +1.00728392e+07 +1.00728392e+07 +1.00728392e+07 +1.00728392e+07 +1.00728392e+07 +1.00772538e+07 +1.00772538e+07 +1.00772538e+07 +1.00772538e+07 +1.00772538e+07 +1.00772538e+07 +1.00772538e+07 +1.00772538e+07 +1.00772538e+07 +1.00772538e+07 +1.00772538e+07 +1.00772538e+07 +1.00772538e+07 +1.00772538e+07 +1.00772538e+07 +1.00772538e+07 +1.00772538e+07 +1.00772538e+07 +1.00772538e+07 +1.00772538e+07 +1.00772538e+07 +1.00772538e+07 +1.00772538e+07 +1.00772538e+07 +1.00772538e+07 +1.00772538e+07 +1.00772538e+07 +1.00772538e+07 +1.00772538e+07 +1.00772538e+07 +1.00772538e+07 +1.00772538e+07 +1.00772538e+07 +1.00772538e+07 +1.00772538e+07 +1.00772538e+07 +1.00772538e+07 +1.00772538e+07 +1.00772538e+07 +1.00772538e+07 +1.00772538e+07 +1.00772538e+07 +1.00772538e+07 +1.00772538e+07 +1.00772538e+07 +1.00772538e+07 +1.00772538e+07 +1.00772538e+07 +1.00772538e+07 +1.00772538e+07 +1.00772538e+07 +1.00772538e+07 +1.00772538e+07 +1.00772538e+07 +1.00772538e+07 +1.00772538e+07 +1.00772538e+07 +1.00772538e+07 +1.00772538e+07 +1.00772538e+07 +1.00816682e+07 +1.00816682e+07 +1.00816682e+07 +1.00816682e+07 +1.00816682e+07 +1.00816682e+07 +1.00816682e+07 +1.00816682e+07 +1.00816682e+07 +1.00816682e+07 +1.00816682e+07 +1.00816682e+07 +1.00816682e+07 +1.00816682e+07 +1.00816682e+07 +1.00816682e+07 +1.00816682e+07 +1.00816682e+07 +1.00816682e+07 +1.00816682e+07 +1.00816682e+07 +1.00816682e+07 +1.00816682e+07 +1.00816682e+07 +1.00816682e+07 +1.00816682e+07 +1.00816682e+07 +1.00816682e+07 +1.00816682e+07 +1.00816682e+07 +1.00816682e+07 +1.00816682e+07 +1.00816682e+07 +1.00816682e+07 +1.00816682e+07 +1.00816682e+07 +1.00816682e+07 +1.00816682e+07 +1.00816682e+07 +1.00816682e+07 +1.00816682e+07 +1.00816682e+07 +1.00816682e+07 +1.00816682e+07 +1.00816682e+07 +1.00816682e+07 +1.00816682e+07 +1.00816682e+07 +1.00816682e+07 +1.00816682e+07 +1.00816682e+07 +1.00816682e+07 +1.00816682e+07 +1.00816682e+07 +1.00816682e+07 +1.00816682e+07 +1.00816682e+07 +1.00816682e+07 +1.00816682e+07 +1.00816682e+07 +1.00860828e+07 +1.00860828e+07 +1.00860828e+07 +1.00860828e+07 +1.00860828e+07 +1.00860828e+07 +1.00860828e+07 +1.00860828e+07 +1.00860828e+07 +1.00860828e+07 +1.00860828e+07 +1.00860828e+07 +1.00860828e+07 +1.00860828e+07 +1.00860828e+07 +1.00860828e+07 +1.00860828e+07 +1.00860828e+07 +1.00860828e+07 +1.00860828e+07 +1.00860828e+07 +1.00860828e+07 +1.00860828e+07 +1.00860828e+07 +1.00860828e+07 +1.00860828e+07 +1.00860828e+07 +1.00860828e+07 +1.00860828e+07 +1.00860828e+07 +1.00860828e+07 +1.00860828e+07 +1.00860828e+07 +1.00860828e+07 +1.00860828e+07 +1.00860828e+07 +1.00860828e+07 +1.00860828e+07 +1.00860828e+07 +1.00860828e+07 +1.00860828e+07 +1.00860828e+07 +1.00860828e+07 +1.00860828e+07 +1.00860828e+07 +1.00860828e+07 +1.00860828e+07 +1.00860828e+07 +1.00860828e+07 +1.00860828e+07 +1.00860828e+07 +1.00860828e+07 +1.00860828e+07 +1.00860828e+07 +1.00860828e+07 +1.00860828e+07 +1.00860828e+07 +1.00860828e+07 +1.00860828e+07 +1.00860828e+07 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/initialSaturation1.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/initialSaturation1.txt new file mode 100644 index 00000000000..90ddc12151e --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/initialSaturation1.txt @@ -0,0 +1,1200 @@ +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e+00 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 +1.00000000e-02 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/initialSaturation2.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/initialSaturation2.txt new file mode 100644 index 00000000000..d5ef52f254b --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/initialSaturation2.txt @@ -0,0 +1,1200 @@ +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +0.00000000e+00 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 +9.90000000e-01 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/permx.geos b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/permx.geos new file mode 100644 index 00000000000..439bd535a86 --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/permx.geos @@ -0,0 +1,1200 @@ +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/permy.geos b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/permy.geos new file mode 100644 index 00000000000..439bd535a86 --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/permy.geos @@ -0,0 +1,1200 @@ +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/permz.geos b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/permz.geos new file mode 100644 index 00000000000..439bd535a86 --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/permz.geos @@ -0,0 +1,1200 @@ +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +5.00000000e+01 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 +2.00000000e+02 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/x.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/x.txt new file mode 100644 index 00000000000..283fc50e7fb --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/x.txt @@ -0,0 +1,10 @@ +5.00000000e-01 +1.50000000e+00 +2.50000000e+00 +3.50000000e+00 +4.50000000e+00 +5.50000000e+00 +6.50000000e+00 +7.50000000e+00 +8.50000000e+00 +9.50000000e+00 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/y.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/y.txt new file mode 100644 index 00000000000..a01763bc5d1 --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/y.txt @@ -0,0 +1,6 @@ +5.00000000e-01 +1.50000000e+00 +2.50000000e+00 +3.50000000e+00 +4.50000000e+00 +5.50000000e+00 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/z.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/z.txt new file mode 100644 index 00000000000..d122a370abe --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/z.txt @@ -0,0 +1,20 @@ +2.50000000e-01 +7.50000000e-01 +1.25000000e+00 +1.75000000e+00 +2.25000000e+00 +2.75000000e+00 +3.25000000e+00 +3.75000000e+00 +4.25000000e+00 +4.75000000e+00 +5.25000000e+00 +5.75000000e+00 +6.25000000e+00 +6.75000000e+00 +7.25000000e+00 +7.75000000e+00 +8.25000000e+00 +8.75000000e+00 +9.25000000e+00 +9.75000000e+00 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/uni_directional_flow_base.xml b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/uni_directional_flow_base.xml new file mode 100644 index 00000000000..eeeefa8277d --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/uni_directional_flow_base.xml @@ -0,0 +1,293 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/uni_directional_flow_interface_condition.xml b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/uni_directional_flow_interface_condition.xml new file mode 100644 index 00000000000..faea9a0d2e4 --- /dev/null +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/uni_directional_flow_interface_condition.xml @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/immiscibleTwoPhase_GravitySegregation_1d_pc_heter2.xml b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/immiscibleTwoPhase_GravitySegregation_1d_pc_heter2.xml deleted file mode 100644 index 01f8c50219d..00000000000 --- a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/immiscibleTwoPhase_GravitySegregation_1d_pc_heter2.xml +++ /dev/null @@ -1,280 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/initialSaturation1.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/initialSaturation1.txt deleted file mode 100644 index 79cccb86897..00000000000 --- a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/initialSaturation1.txt +++ /dev/null @@ -1,10 +0,0 @@ -0.4 -0.4 -0.8 -0.8 -0.8 -0.8 -0.8 -0.8 -0.8 -0.8 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/initialSaturation2.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/initialSaturation2.txt deleted file mode 100644 index 72c544974fe..00000000000 --- a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/initialSaturation2.txt +++ /dev/null @@ -1,10 +0,0 @@ -0.6 -0.6 -0.2 -0.2 -0.2 -0.2 -0.2 -0.2 -0.2 -0.2 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/permx.geos b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/permx.geos deleted file mode 100644 index ec8beb6c503..00000000000 --- a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/permx.geos +++ /dev/null @@ -1,10 +0,0 @@ -112.5 -112.5 -112.5 -112.5 -112.5 -50 -50 -50 -50 -50 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/permy.geos b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/permy.geos deleted file mode 100644 index ec8beb6c503..00000000000 --- a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/permy.geos +++ /dev/null @@ -1,10 +0,0 @@ -112.5 -112.5 -112.5 -112.5 -112.5 -50 -50 -50 -50 -50 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/permz.geos b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/permz.geos deleted file mode 100644 index ec8beb6c503..00000000000 --- a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/permz.geos +++ /dev/null @@ -1,10 +0,0 @@ -112.5 -112.5 -112.5 -112.5 -112.5 -50 -50 -50 -50 -50 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/tables/jFunction.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/tables/jFunction.txt deleted file mode 100644 index dfd48c60a6b..00000000000 --- a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/tables/jFunction.txt +++ /dev/null @@ -1,13 +0,0 @@ -4.331729359 -3.523266264 -2.677103439 -2.356150157 -2.166062360 -2.034158727 -1.934627222 -1.855494313 -1.790286970 -1.735134860 -1.687551617 -1.666049754 - diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/tables/phaseVolumeFraction_water.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/tables/phaseVolumeFraction_water.txt deleted file mode 100644 index 4c7e1f01e40..00000000000 --- a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/tables/phaseVolumeFraction_water.txt +++ /dev/null @@ -1,13 +0,0 @@ -0 -0.05 -0.15 -0.25 -0.35 -0.45 -0.55 -0.65 -0.75 -0.85 -0.95 -1 - diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/x.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/x.txt deleted file mode 100644 index 7ed6ff82de6..00000000000 --- a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/x.txt +++ /dev/null @@ -1 +0,0 @@ -5 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/y.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/y.txt deleted file mode 100644 index 7ed6ff82de6..00000000000 --- a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/y.txt +++ /dev/null @@ -1 +0,0 @@ -5 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/z.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/z.txt deleted file mode 100644 index d71cc528224..00000000000 --- a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/immiscible_GS_1d_pc_heter_famousCase_withIC/z.txt +++ /dev/null @@ -1,10 +0,0 @@ -5 -15 -25 -35 -45 -55 -65 -75 -85 -95 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/tables/jFunction_linear.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/tables/jFunction_linear.txt deleted file mode 100644 index c2cba8f9783..00000000000 --- a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/tables/jFunction_linear.txt +++ /dev/null @@ -1,2 +0,0 @@ -10000 -3000 diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/tables/phaseVolumeFraction_water_linear.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/tables/phaseVolumeFraction_water_linear.txt deleted file mode 100755 index 0d66ea1aee9..00000000000 --- a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/tables/phaseVolumeFraction_water_linear.txt +++ /dev/null @@ -1,2 +0,0 @@ -0 -1 diff --git a/src/coreComponents/constitutive/capillaryPressure/BrooksCoreyCapillaryPressure.hpp b/src/coreComponents/constitutive/capillaryPressure/BrooksCoreyCapillaryPressure.hpp index 4a7816683dd..0d71fcbc948 100644 --- a/src/coreComponents/constitutive/capillaryPressure/BrooksCoreyCapillaryPressure.hpp +++ b/src/coreComponents/constitutive/capillaryPressure/BrooksCoreyCapillaryPressure.hpp @@ -196,6 +196,8 @@ BrooksCoreyCapillaryPressureUpdate:: // compute first gas-oil capillary pressure as a function of gas-phase vol fraction integer const ip_gas = m_phaseOrder[CapillaryPressureBase::PhaseType::GAS]; integer const ip_oil = m_phaseOrder[CapillaryPressureBase::PhaseType::OIL]; + + GEOS_UNUSED_VAR( ip_gas ); if( ip_oil >= 0 ) { real64 const volFracScaled = (phaseVolFraction[ip_oil] - m_phaseMinVolumeFraction[ip_oil]) * volFracScaleInv; diff --git a/src/coreComponents/constitutive/capillaryPressure/JFunctionCapillaryPressure.hpp b/src/coreComponents/constitutive/capillaryPressure/JFunctionCapillaryPressure.hpp index 80815e98236..5e2f885cbf6 100644 --- a/src/coreComponents/constitutive/capillaryPressure/JFunctionCapillaryPressure.hpp +++ b/src/coreComponents/constitutive/capillaryPressure/JFunctionCapillaryPressure.hpp @@ -271,6 +271,7 @@ JFunctionCapillaryPressure::KernelWrapper:: integer const ipOil = m_phaseOrder[PT::OIL]; integer const ipGas = m_phaseOrder[PT::GAS]; + GEOS_UNUSED_VAR( ipOil ); // apply multiplier real64 capPresWater_J = phaseCapPres[ipWater] / jFuncMultiplier[0]; // std::cout << GEOS_FMT( " JM_2 = ( {:4.2e} )", jFuncMultiplier[0] ); diff --git a/src/coreComponents/constitutive/capillaryPressure/TableCapillaryPressure.hpp b/src/coreComponents/constitutive/capillaryPressure/TableCapillaryPressure.hpp index 949d431792a..7a018204287 100644 --- a/src/coreComponents/constitutive/capillaryPressure/TableCapillaryPressure.hpp +++ b/src/coreComponents/constitutive/capillaryPressure/TableCapillaryPressure.hpp @@ -199,6 +199,8 @@ TableCapillaryPressure::KernelWrapper:: integer const ipOil = m_phaseOrder[PT::OIL]; integer const ipGas = m_phaseOrder[PT::GAS]; + GEOS_UNUSED_VAR( ipOil ); + // put capillary pressure on the wetting phase real64 capPresWater = phaseCapPres[ipWater]; array1d input(1); diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp index 7bc576686dc..5b60a07045d 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp @@ -215,7 +215,7 @@ // ***** Create FaceElements ***** forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, MeshLevel & meshLevel, - string_array const & regionNames ) + string_array const & GEOS_UNUSED_PARAM( regionNames )) { FaceManager const & faceManager = meshLevel.getFaceManager(); @@ -617,7 +617,7 @@ m_interfaceConstitutivePairs[surfaceRegionIndex][1] = std::make_tuple( relPerm1, m_interfaceRegionByConnector.clear(); forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( std::string const &, MeshLevel & meshLevel, - string_array const & regionNames ) + string_array const & GEOS_UNUSED_PARAM( regionNames )) { // Access the face manager and retrieve the face set group for the current mesh level FaceManager const & faceManager = meshLevel.getFaceManager(); diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp index 37b67a7852c..f9535bbadba 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp @@ -164,7 +164,7 @@ static void local_solver( real64 uT, stdVector< real64 > saturations, stdVector< converged = 0; bool damping = true; bool bisection = false; - bool lineSearch = false; + // bool lineSearch = false; bool newton_path = false; // Local newton loop: @@ -483,8 +483,8 @@ static void local_solver( real64 uT, stdVector< real64 > saturations, stdVector< // While loop (newton loop) int iter = 0; int div = 0; - int ext_iter0 = 0; - int ext_iter1 = 0; + // int ext_iter0 = 0; + // int ext_iter1 = 0; real64 next_Pc_int = 0.0; real64 old_Pc_int = 0.0; real64 old_residual = 0.0; @@ -701,8 +701,8 @@ static void local_solver( real64 uT, stdVector< real64 > saturations, stdVector< real64 dGravHead_dP[2][2]{}; real64 capGrad[2]{}; - real64 capPresIC[2][2]{}; - real64 jFMultiplier[2][2]{}; + // real64 capPresIC[2][2]{}; + // real64 jFMultiplier[2][2]{}; real64 dCapGrad_dP[2][2]{}; real64 dCapGrad_dS[2][2]{}; @@ -809,7 +809,7 @@ static void local_solver( real64 uT, stdVector< real64 > saturations, stdVector< dGravHead_dP[ip][ke] += signTix[ke] * dTransHat_dP[ix] * dGravHead_dTrans; - real64 constexpr eps = 1e-18; + // real64 constexpr eps = 1e-18; real64 dCapPres_dS = dCapPres1_dPhaseVolFrac[0][0][ip][ip]; if( ke == 1 && ix == 0 ) @@ -869,7 +869,7 @@ static void local_solver( real64 uT, stdVector< real64 > saturations, stdVector< /// Three Forces Flux Contribution: 1- Viscous 2- Gravitational 3- Capillary constexpr int sign[2] = {1, -1}; - real64 constexpr eps = 0.0; + // real64 constexpr eps = 0.0; // loop over phases for( integer ip = 0; ip < 2; ++ip ) @@ -2196,7 +2196,7 @@ class FluxComputeInterfaceConditionKernel : public FluxComputeKernel< NUM_EQN, N real64 capGrad[numEqn]{}; // real64 capPresIC[numEqn][2]{}; - real64 jFMultiplier[numEqn][2]{}; + // real64 jFMultiplier[numEqn][2]{}; real64 dCapGrad_dP[numEqn][2]{}; real64 dCapGrad_dS[numEqn][2]{}; @@ -2216,7 +2216,7 @@ class FluxComputeInterfaceConditionKernel : public FluxComputeKernel< NUM_EQN, N real64 gravCoefHat[numEqn]{}; real64 uT = 0; - real64 total_mobility = 0; + // real64 total_mobility = 0; real64 duT_dP[numEqn]{}; real64 duT_dS[numEqn]{}; @@ -2236,7 +2236,7 @@ class FluxComputeInterfaceConditionKernel : public FluxComputeKernel< NUM_EQN, N stdVector< real64 > saturations = {m_phaseVolFrac[seri[0]][sesri[0]][sei[0]][0], m_phaseVolFrac[seri[1]][sesri[1]][sei[1]][0] }; stdVector< real64 > pressures = {m_pres[seri[0]][sesri[0]][sei[0]], m_pres[seri[1]][sesri[1]][sei[1]] }; - bool isJfunction = 0; + // bool isJfunction = 0; // loop over phases for( integer ip = 0; ip < m_numPhases; ++ip ) @@ -2507,12 +2507,12 @@ class FluxComputeInterfaceConditionKernel : public FluxComputeKernel< NUM_EQN, N // clear working arrays real64 halfFluxVal[numEqn][2]{}; - real64 dhalfFlux1_dP[numEqn][2]{}; - real64 dhalfFlux1_dS[numEqn][2]{}; - real64 dhalfFlux2_dP[numEqn][2]{}; - real64 dhalfFlux2_dS[numEqn][2]{}; - real64 dhalfFlux_duT[numEqn][2]{}; - real64 dhalfFlux_dpc[numEqn][2]{}; + // real64 dhalfFlux1_dP[numEqn][2]{}; + // real64 dhalfFlux1_dS[numEqn][2]{}; + // real64 dhalfFlux2_dP[numEqn][2]{}; + // real64 dhalfFlux2_dS[numEqn][2]{}; + // real64 dhalfFlux_duT[numEqn][2]{}; + // real64 dhalfFlux_dpc[numEqn][2]{}; // stdVector< real64 > JFMultipliers = {jFMultiplier[0][0], jFMultiplier[0][1]}; From 5f7e6c0a132da89c881e3b9b8422463df3631de5 Mon Sep 17 00:00:00 2001 From: Omar Duran Date: Wed, 4 Feb 2026 22:47:42 -0800 Subject: [PATCH 096/102] wip: adding interface condition test to CmakeList --- .../BrooksCoreyCapillaryPressure.hpp | 49 +- .../TableCapillaryPressure.cpp | 2 +- .../TableCapillaryPressure.hpp | 10 +- .../VanGenuchtenCapillaryPressure.hpp | 10 +- .../testCO2SpycherPruessModels.cpp.uncrustify | 0 .../fluidFlowTests/CMakeLists.txt | 1 + .../testImmiscibleInterfaceConditions.cpp | 39 +- .../fluidFlow/ImmiscibleMultiphaseFlow.cpp | 3063 ++++++++--------- .../ImmiscibleMultiphaseKernels.hpp | 273 +- 9 files changed, 1741 insertions(+), 1706 deletions(-) create mode 100644 src/coreComponents/constitutive/unitTests/testCO2SpycherPruessModels.cpp.uncrustify diff --git a/src/coreComponents/constitutive/capillaryPressure/BrooksCoreyCapillaryPressure.hpp b/src/coreComponents/constitutive/capillaryPressure/BrooksCoreyCapillaryPressure.hpp index 0d71fcbc948..39b61e786f7 100644 --- a/src/coreComponents/constitutive/capillaryPressure/BrooksCoreyCapillaryPressure.hpp +++ b/src/coreComponents/constitutive/capillaryPressure/BrooksCoreyCapillaryPressure.hpp @@ -59,8 +59,8 @@ class BrooksCoreyCapillaryPressureUpdate final : public CapillaryPressureBaseUpd GEOS_HOST_DEVICE void computeInv( arraySlice1d< real64, compflow::USD_PHASE - 1 > const & phaseVolFraction, - arraySlice1d< real64 const, cappres::USD_CAPPRES - 2 > const & phaseCapPres, - arraySlice2d< real64, cappres::USD_CAPPRES_DS - 2 > const & dPhaseCapPres_dPhaseVolFrac ) const; + arraySlice1d< real64 const, cappres::USD_CAPPRES - 2 > const & phaseCapPres, + arraySlice2d< real64, cappres::USD_CAPPRES_DS - 2 > const & dPhaseCapPres_dPhaseVolFrac ) const; GEOS_HOST_DEVICE virtual void update( localIndex const k, @@ -85,20 +85,20 @@ class BrooksCoreyCapillaryPressureUpdate final : public CapillaryPressureBaseUpd real64 & phaseCapPressure, real64 & dPhaseCapPressure_dVolFrac ); - -GEOS_HOST_DEVICE -GEOS_FORCE_INLINE -static void -evaluateBrooksCoreyFunctionInv( real64 const phaseCapPressure, - int const ip, - real64 const volFracScaleInv, - real64 const exponentInv, - real64 const entryPressure, - real64 const maxCapPres_eps, - real64 const phaseMinVolumeFraction, - arrayView1d< integer const > const phaseOrder, - real64 & phaseVolFraction, - real64 & dPhaseCapPressure_dVolFrac ); + + GEOS_HOST_DEVICE + GEOS_FORCE_INLINE + static void + evaluateBrooksCoreyFunctionInv( real64 const phaseCapPressure, + int const ip, + real64 const volFracScaleInv, + real64 const exponentInv, + real64 const entryPressure, + real64 const maxCapPres_eps, + real64 const phaseMinVolumeFraction, + arrayView1d< integer const > const phaseOrder, + real64 & phaseVolFraction, + real64 & dPhaseCapPressure_dVolFrac ); arrayView1d< real64 const > m_phaseMinVolumeFraction; arrayView1d< real64 const > m_phaseCapPressureExponentInv; @@ -111,9 +111,6 @@ evaluateBrooksCoreyFunctionInv( real64 const phaseCapPressure, - - - class BrooksCoreyCapillaryPressure : public CapillaryPressureBase { public: @@ -222,8 +219,8 @@ GEOS_HOST_DEVICE inline void BrooksCoreyCapillaryPressureUpdate:: computeInv( arraySlice1d< real64, compflow::USD_PHASE - 1 > const & phaseVolFraction, - arraySlice1d< real64 const, cappres::USD_CAPPRES - 2 > const & phaseCapPres, - arraySlice2d< real64, cappres::USD_CAPPRES_DS - 2 > const & dPhaseCapPres_dPhaseVolFrac ) const + arraySlice1d< real64 const, cappres::USD_CAPPRES - 2 > const & phaseCapPres, + arraySlice2d< real64, cappres::USD_CAPPRES_DS - 2 > const & dPhaseCapPres_dPhaseVolFrac ) const { LvArray::forValuesInSlice( dPhaseCapPres_dPhaseVolFrac, []( real64 & val ){ val = 0.0; } ); @@ -268,7 +265,7 @@ BrooksCoreyCapillaryPressureUpdate:: m_phaseOrder, phaseVolFraction[ip_water], dPhaseCapPres_dPhaseVolFrac[ip_water][ip_water] ); - phaseVolFraction[ip_gas] = 1.0 - phaseVolFraction[ip_water]; + phaseVolFraction[ip_gas] = 1.0 - phaseVolFraction[ip_water]; } @@ -306,7 +303,7 @@ BrooksCoreyCapillaryPressureUpdate:: // m_phaseOrder, // phaseVolFraction[ip_gas], // dPhaseCapPres_dPhaseVolFrac[ip_gas][ip_gas] ); - // phaseVolFraction[ip_water] = 1.0 - phaseVolFraction[ip_gas]; + // phaseVolFraction[ip_water] = 1.0 - phaseVolFraction[ip_gas]; // } } @@ -357,7 +354,7 @@ BrooksCoreyCapillaryPressureUpdate:: real64 & phaseVolFraction, real64 & dPhaseCapPressure_dVolFrac ) { - + phaseVolFraction = 0.0; real64 value = 0.0; @@ -370,7 +367,7 @@ BrooksCoreyCapillaryPressureUpdate:: if( phaseCapPressure <= maxCapPres_eps && phaseCapPressure >= entryPressure ) { // intermediate value - real64 const val = pow( entryPressure, exponentInv) / pow( phaseCapPressure , exponentInv + 1 ); + real64 const val = pow( entryPressure, exponentInv ) / pow( phaseCapPressure, exponentInv + 1 ); value = (phaseCapPressure * val) * volFracScaleInv + phaseMinVolumeFraction; // entryPressure * (S_w)^( - 1 / exponentInv ) dPhaseCapPressure_dVolFrac = -dScaledWettingPhaseVolFrac_dVolFrac * val * exponentInv; @@ -379,7 +376,7 @@ BrooksCoreyCapillaryPressureUpdate:: else // enforce a constant and bounded capillary pressure { real64 const val = (phaseCapPressure > maxCapPres_eps) - ? pow( entryPressure, exponentInv) / pow( maxCapPres_eps , exponentInv) : 1.0; + ? pow( entryPressure, exponentInv ) / pow( maxCapPres_eps, exponentInv ) : 1.0; value = val * volFracScaleInv + phaseMinVolumeFraction; phaseVolFraction = (ip == ip_oil) ? 1.0 - value : value; } diff --git a/src/coreComponents/constitutive/capillaryPressure/TableCapillaryPressure.cpp b/src/coreComponents/constitutive/capillaryPressure/TableCapillaryPressure.cpp index 1fbc230a03e..b925627ff4b 100644 --- a/src/coreComponents/constitutive/capillaryPressure/TableCapillaryPressure.cpp +++ b/src/coreComponents/constitutive/capillaryPressure/TableCapillaryPressure.cpp @@ -72,7 +72,7 @@ TableCapillaryPressure::TableCapillaryPressure( std::string const & name, registerWrapper( viewKeyStruct::inverseCapPresWrappersString(), &m_inverseCapPresWrappers ). setSizedFromParent( 0 ). - setRestartFlags( RestartFlags::NO_WRITE ); + setRestartFlags( RestartFlags::NO_WRITE ); } void TableCapillaryPressure::postInputInitialization() diff --git a/src/coreComponents/constitutive/capillaryPressure/TableCapillaryPressure.hpp b/src/coreComponents/constitutive/capillaryPressure/TableCapillaryPressure.hpp index 7a018204287..5d132d3636a 100644 --- a/src/coreComponents/constitutive/capillaryPressure/TableCapillaryPressure.hpp +++ b/src/coreComponents/constitutive/capillaryPressure/TableCapillaryPressure.hpp @@ -127,7 +127,7 @@ class TableCapillaryPressure : public CapillaryPressureBase array1d< TableFunction::KernelWrapper > m_capPresKernelWrappers; array1d< TableFunction::KernelWrapper > m_inverseCapPresWrappers; - std::vector< std::shared_ptr > m_inverseTables; + std::vector< std::shared_ptr< TableFunction > > m_inverseTables; }; @@ -203,7 +203,7 @@ TableCapillaryPressure::KernelWrapper:: // put capillary pressure on the wetting phase real64 capPresWater = phaseCapPres[ipWater]; - array1d input(1); + array1d< real64 > input( 1 ); input[0] = capPresWater; auto inputSlice = input.toSliceConst(); @@ -211,9 +211,9 @@ TableCapillaryPressure::KernelWrapper:: m_capPresKernelWrappers[0].compute( &(phaseCapPres)[ipWater], &(dPhaseCapPres_dPhaseVolFrac)[ipWater][ipWater] ); phaseVolFraction[ipWater] = - m_inverseCapPresWrappers[0].compute( inputSlice, - &(dPhaseCapPres_dPhaseVolFrac)[ipWater][ipWater] ); - phaseVolFraction[ipGas] = 1.0 - phaseVolFraction[ipWater]; + m_inverseCapPresWrappers[0].compute( inputSlice, + &(dPhaseCapPres_dPhaseVolFrac)[ipWater][ipWater] ); + phaseVolFraction[ipGas] = 1.0 - phaseVolFraction[ipWater]; } diff --git a/src/coreComponents/constitutive/capillaryPressure/VanGenuchtenCapillaryPressure.hpp b/src/coreComponents/constitutive/capillaryPressure/VanGenuchtenCapillaryPressure.hpp index 798815cd877..6ac95221027 100644 --- a/src/coreComponents/constitutive/capillaryPressure/VanGenuchtenCapillaryPressure.hpp +++ b/src/coreComponents/constitutive/capillaryPressure/VanGenuchtenCapillaryPressure.hpp @@ -56,11 +56,11 @@ class VanGenuchtenCapillaryPressureUpdate final : public CapillaryPressureBaseUp void compute( arraySlice1d< real64 const, compflow::USD_PHASE - 1 > const & phaseVolFraction, arraySlice1d< real64, cappres::USD_CAPPRES - 2 > const & phaseCapPres, arraySlice2d< real64, cappres::USD_CAPPRES_DS - 2 > const & dPhaseCapPres_dPhaseVolFrac ) const; - + GEOS_HOST_DEVICE void computeInv( arraySlice1d< real64 const, compflow::USD_PHASE - 1 > const & phaseVolFraction, - arraySlice1d< real64, cappres::USD_CAPPRES - 2 > const & phaseCapPres, - arraySlice2d< real64, cappres::USD_CAPPRES_DS - 2 > const & dPhaseCapPres_dPhaseVolFrac ) const; + arraySlice1d< real64, cappres::USD_CAPPRES - 2 > const & phaseCapPres, + arraySlice2d< real64, cappres::USD_CAPPRES_DS - 2 > const & dPhaseCapPres_dPhaseVolFrac ) const; GEOS_HOST_DEVICE virtual void update( localIndex const k, @@ -198,8 +198,8 @@ GEOS_HOST_DEVICE inline void VanGenuchtenCapillaryPressureUpdate:: computeInv( arraySlice1d< real64 const, compflow::USD_PHASE - 1 > const & phaseVolFraction, - arraySlice1d< real64, cappres::USD_CAPPRES - 2 > const & phaseCapPres, - arraySlice2d< real64, cappres::USD_CAPPRES_DS - 2 > const & dPhaseCapPres_dPhaseVolFrac ) const + arraySlice1d< real64, cappres::USD_CAPPRES - 2 > const & phaseCapPres, + arraySlice2d< real64, cappres::USD_CAPPRES_DS - 2 > const & dPhaseCapPres_dPhaseVolFrac ) const { LvArray::forValuesInSlice( dPhaseCapPres_dPhaseVolFrac, []( real64 & val ){ val = 0.0; } ); diff --git a/src/coreComponents/constitutive/unitTests/testCO2SpycherPruessModels.cpp.uncrustify b/src/coreComponents/constitutive/unitTests/testCO2SpycherPruessModels.cpp.uncrustify new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/coreComponents/integrationTests/fluidFlowTests/CMakeLists.txt b/src/coreComponents/integrationTests/fluidFlowTests/CMakeLists.txt index 951cac7c502..9a89d938e2e 100644 --- a/src/coreComponents/integrationTests/fluidFlowTests/CMakeLists.txt +++ b/src/coreComponents/integrationTests/fluidFlowTests/CMakeLists.txt @@ -4,6 +4,7 @@ set( gtest_geosx_tests testThermalSinglePhaseFlow.cpp testTransmissibility.cpp testImmiscibleMultiphaseFlow.cpp + testImmiscibleInterfaceConditions.cpp testSinglePhaseMFDPolyhedral.cpp testSinglePhaseReactiveTransport.cpp ) diff --git a/src/coreComponents/integrationTests/fluidFlowTests/testImmiscibleInterfaceConditions.cpp b/src/coreComponents/integrationTests/fluidFlowTests/testImmiscibleInterfaceConditions.cpp index 95431c366a4..be96c05aa4d 100644 --- a/src/coreComponents/integrationTests/fluidFlowTests/testImmiscibleInterfaceConditions.cpp +++ b/src/coreComponents/integrationTests/fluidFlowTests/testImmiscibleInterfaceConditions.cpp @@ -26,11 +26,11 @@ #include "constitutive/fluid/twophaseimmisciblefluid/TwoPhaseImmiscibleFluid.hpp" #include "physicsSolvers/PhysicsSolverManager.hpp" #include "physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp" -#include "unitTests/fluidFlowTests/testCompFlowUtils.hpp" +#include "integrationTests/fluidFlowTests/testCompFlowUtils.hpp" #include "constitutive/unitTests/FluidModelTest.hpp" #include "constitutive/unitTests/FluidModelTest_impl.hpp" #include "common/initializeEnvironment.hpp" -#include "unitTests/constitutiveTests/constitutiveTestHelpers.hpp" +#include "constitutive/relativePermeability/unitTests/constitutiveTestHelpers.hpp" #include "functions/FunctionManager.hpp" #include "constitutive/capillaryPressure/CapillaryPressureFields.hpp" @@ -481,7 +481,7 @@ RelativePermeabilityBase & makeBrooksCoreyRelPerm( string const & name, Group & class ImmiscibleInterfaceConditionsTest : public FluidModelTest< TwoPhaseImmiscibleFluid, 2 > { public: - ImmiscibleInterfaceConditionsTest(): state( std::make_unique< CommandLineOptions >( g_commandLineOptions )), + ImmiscibleInterfaceConditionsTest(): state( std::make_unique< CommandLineOptions >( g_commandLineOptions )), m_parent( "TestParentGroup", m_node ) {} @@ -547,8 +547,8 @@ TEST_F( ImmiscibleInterfaceConditionsTest, LocalNonlinearSolverConvergence ) stdVector< real64 > gravCoefs = {465.97500000000002, 515.02499999999998}; - stdVector< real64 > phi = {0.0, 0.0}; - stdVector< real64 > grad_phi = {0.0, 0.0, 0.0, 0.0}; + std::vector< real64 > phi = {0.0, 0.0}; + std::vector< real64 > grad_phi = {0.0, 0.0, 0.0, 0.0}; std::ofstream outFile( "local_solver_results.csv" ); @@ -586,9 +586,18 @@ TEST_F( ImmiscibleInterfaceConditionsTest, LocalNonlinearSolverConvergence ) auto t0 = std::chrono::high_resolution_clock::now(); + // Define missing arguments for the updated signature + stdVector< real64 > cellCenterDuT = { 0.0, 0.0 }; + stdVector< real64 > cellCenterDens = { 0.0, 0.0 }; + stdVector< real64 > cellCenterDens_dP = { 0.0, 0.0 }; + std::vector< real64 > grad_phi_P = { 0.0, 0.0 }; + std::vector< real64 > grad_phi_S = { 0.0, 0.0 }; + bool converged; + // Call the GEOS local solver geos::immiscibleMultiphaseKernels::local_solver( uT, saturations, pressures, JFMultipliers, trappedSats1, trappedSats2, transHats, dTransHats_dP, gravCoefHats, gravCoefs, - relPerms, capPressures, fluids, phi, grad_phi ); + cellCenterDuT, cellCenterDens, cellCenterDens_dP, + relPerms, capPressures, fluids, phi, grad_phi_P, grad_phi_S, converged ); auto t1 = std::chrono::high_resolution_clock::now(); std::chrono::duration elapsed = t1 - t0; @@ -600,17 +609,17 @@ std::cout << "Local solver time: " << elapsed.count() << " s" << std::endl; outFile << GEOS_FMT( ",{:10.10e}", saturations[1] ); outFile << GEOS_FMT( ",{:10.10e}", phi[0] ); outFile << GEOS_FMT( ",{:10.10e}", phi[1] ); - outFile << GEOS_FMT( ",{:10.10e}", grad_phi[0] ); - outFile << GEOS_FMT( ",{:10.10e}", grad_phi[1] ); - outFile << GEOS_FMT( ",{:10.10e}", grad_phi[2] ); - outFile << GEOS_FMT( ",{:10.10e}", grad_phi[3] ); + outFile << GEOS_FMT( ",{:10.10e}", grad_phi_P[0] ); + outFile << GEOS_FMT( ",{:10.10e}", grad_phi_P[1] ); + outFile << GEOS_FMT( ",{:10.10e}", grad_phi_S[0] ); + outFile << GEOS_FMT( ",{:10.10e}", grad_phi_S[1] ); outFile << std::endl; phi[0] = 0; phi[1] = 0; - grad_phi[0] = 0; - grad_phi[1] = 0; - grad_phi[2] = 0; - grad_phi[3] = 0; + grad_phi_P[0] = 0; + grad_phi_P[1] = 0; + grad_phi_S[0] = 0; + grad_phi_S[1] = 0; // } // } @@ -674,4 +683,4 @@ int main( int argc, char * *argv ) // sat[1] = 1 - sat[0]; // } -// } \ No newline at end of file +// } diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp index 5b60a07045d..ec169a7e330 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp @@ -31,1616 +31,1615 @@ #include "constitutive/capillaryPressure/CapillaryPressureFields.hpp" #include "constitutive/capillaryPressure/CapillaryPressureSelector.hpp" #include "constitutive/relativePermeability/RelativePermeabilitySelector.hpp" - + #include "fieldSpecification/EquilibriumInitialCondition.hpp" #include "fieldSpecification/SourceFluxBoundaryCondition.hpp" #include "physicsSolvers/fluidFlow/SourceFluxStatistics.hpp" #include "physicsSolvers/LogLevelsInfo.hpp" - + #include "constitutive/ConstitutivePassThru.hpp" #include "constitutive/fluid/twophaseimmisciblefluid/TwoPhaseImmiscibleFluid.hpp" - + #include - + #if defined( __INTEL_COMPILER ) #pragma GCC optimize "O0" #endif - - namespace geos - { - - using namespace dataRepository; - using namespace constitutive; - using namespace fields::immiscibleMultiphaseFlow; - using namespace immiscibleMultiphaseKernels; - - - ImmiscibleMultiphaseFlow::ImmiscibleMultiphaseFlow( const string & name, - Group * const parent ) - : - FlowSolverBase( name, parent ), - m_numPhases( 2 ), - m_hasCapPressure( false ), - m_useTotalMassEquation ( 1 ) - { - this->registerWrapper( viewKeyStruct::inputTemperatureString(), &m_inputTemperature ). - setInputFlag( InputFlags::REQUIRED ). - setDescription( "Temperature" ); - - this->registerWrapper( viewKeyStruct::useTotalMassEquationString(), &m_useTotalMassEquation ). - setSizedFromParent( 0 ). - setInputFlag( InputFlags::OPTIONAL ). - setApplyDefaultValue( 1 ). - setDescription( "Flag indicating whether total mass equation is used" ); - - this->registerWrapper( viewKeyStruct::gravityDensitySchemeString(), &m_gravityDensityScheme ). - setSizedFromParent( 0 ). - setInputFlag( InputFlags::OPTIONAL ). - setApplyDefaultValue( GravityDensityScheme::ArithmeticAverage ). - setDescription( "Scheme for density treatment in gravity" ); - - this->registerWrapper( viewKeyStruct::solutionChangeScalingFactorString(), &m_solutionChangeScalingFactor ). - setSizedFromParent( 0 ). - setInputFlag( InputFlags::OPTIONAL ). - setApplyDefaultValue( 0.5 ). - setDescription( "Damping factor for solution change targets" ); - this->registerWrapper( viewKeyStruct::targetRelativePresChangeString(), &m_targetRelativePresChange ). - setSizedFromParent( 0 ). - setInputFlag( InputFlags::OPTIONAL ). - setApplyDefaultValue( 0.2 ). - setDescription( "Target (relative) change in pressure in a time step (expected value between 0 and 1)" ); - this->registerWrapper( viewKeyStruct::targetPhaseVolFracChangeString(), &m_targetPhaseVolFracChange ). - setSizedFromParent( 0 ). - setInputFlag( InputFlags::OPTIONAL ). - setApplyDefaultValue( 0.2 ). - setDescription( "Target (absolute) change in phase volume fraction in a time step" ); - - this->registerWrapper( viewKeyStruct::interfaceFaceSetNamesString(), - &m_interfaceFaceSetNames ). - setInputFlag( InputFlags::OPTIONAL ). - setDescription( "Names of the interface face sets" ); - } - - void ImmiscibleMultiphaseFlow::postInputInitialization() - { - FlowSolverBase::postInputInitialization(); - } - - void ImmiscibleMultiphaseFlow::registerDataOnMesh( Group & meshBodies ) - { - FlowSolverBase::registerDataOnMesh( meshBodies ); - - // 0. Find a "reference" fluid model name (at this point, models are already attached to subregions) - forDiscretizationOnMeshTargets( meshBodies, [&]( string const &, - MeshLevel & mesh, - string_array const & regionNames ) - { - mesh.getElemManager().forElementSubRegions( regionNames, - [&]( localIndex const, - ElementSubRegionBase & subRegion ) - { - // If at least one region has a capillary pressure model, consider it enabled for all - string const capPresName = getConstitutiveName< CapillaryPressureBase >( subRegion ); - if( !capPresName.empty() ) - { - m_hasCapPressure = true; - } - } ); - } ); - - m_numDofPerCell = m_numPhases; - - // 2. Register and resize all fields as necessary - forDiscretizationOnMeshTargets( meshBodies, [&]( string const &, - MeshLevel & mesh, - string_array const & regionNames ) - { - mesh.getElemManager().forElementSubRegions( regionNames, - [&]( localIndex const, - ElementSubRegionBase & subRegion ) - { - if( m_hasCapPressure ) - { - subRegion.registerWrapper< string >( viewKeyStruct::capPressureNamesString() ). - setPlotLevel( PlotLevel::NOPLOT ). - setRestartFlags( RestartFlags::NO_WRITE ). - setSizedFromParent( 0 ). - setDescription( "Name of the capillary pressure constitutive model to use" ). - reference(); - - string & capPresName = subRegion.getReference< string >( viewKeyStruct::capPressureNamesString() ); - capPresName = getConstitutiveName< CapillaryPressureBase >( subRegion ); - GEOS_THROW_IF( capPresName.empty(), - GEOS_FMT( "{}: Capillary pressure model not found on subregion {}", - getDataContext(), subRegion.getDataContext() ), - InputError ); - } - - // The resizing of the arrays needs to happen here, before the call to initializePreSubGroups, - // to make sure that the dimensions are properly set before the timeHistoryOutput starts its initialization. - subRegion.registerField< phaseVolumeFraction >( getName() ). - reference().resizeDimension< 1 >( m_numPhases ); - - subRegion.registerField< phaseVolumeFraction_n >( getName() ). - reference().resizeDimension< 1 >( m_numPhases ); - - subRegion.registerField< bcPhaseVolumeFraction >( getName() ). - reference().resizeDimension< 1 >( m_numPhases ); - - subRegion.registerField< phaseMass >( getName() ). - reference().resizeDimension< 1 >( m_numPhases ); - - subRegion.registerField< phaseMass_n >( getName() ). - reference().resizeDimension< 1 >( m_numPhases ); - - subRegion.registerField< phaseMobility >( getName() ). - reference().resizeDimension< 1 >( m_numPhases ); - - subRegion.registerField< dPhaseMobility >( getName() ). - reference().resizeDimension< 1, 2 >( m_numPhases, m_numPhases ); // dP, dS - - } ); - - } ); - } - - void ImmiscibleMultiphaseFlow::setConstitutiveNames( ElementSubRegionBase & subRegion ) const - { - setConstitutiveName< TwoPhaseImmiscibleFluid >( subRegion, viewKeyStruct::fluidNamesString(), "two phase immiscible fluid" ); - - setConstitutiveName< RelativePermeabilityBase >( subRegion, viewKeyStruct::relPermNamesString(), "relative permeability" ); - } - - void ImmiscibleMultiphaseFlow::initializePreSubGroups() - { - m_linearSolverParameters.get().mgr.strategy = LinearSolverParameters::MGR::StrategyType::immiscibleMultiphaseFVM; - - FlowSolverBase::initializePreSubGroups(); - - DomainPartition & domain = this->getGroupByPath< DomainPartition >( "/Problem/domain" ); - - forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, - MeshLevel & mesh, - string_array const & regionNames ) - { - mesh.getElemManager().forElementSubRegions( regionNames, - [&]( localIndex const, - ElementSubRegionBase & subRegion ) - { - arrayView1d< real64 > const temp = subRegion.getField< fields::flow::temperature >(); - temp.setValues< parallelHostPolicy >( m_inputTemperature ); - } ); - } ); - - // ***** Create FaceElements ***** - forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, - MeshLevel & meshLevel, - string_array const & GEOS_UNUSED_PARAM( regionNames )) - { - - FaceManager const & faceManager = meshLevel.getFaceManager(); - Group const & faceSetGroup = faceManager.sets(); - ElementRegionManager & elemManager = meshLevel.getElemManager(); - m_interfaceConstitutivePairs.resize( m_interfaceFaceSetNames.size() ); - - // this is the FaceElement Level - for( size_t surfaceRegionIndex=0; surfaceRegionIndex < m_interfaceFaceSetNames.size(); ++surfaceRegionIndex ) - { - string const & faceSetName = m_interfaceFaceSetNames[surfaceRegionIndex]; - SortedArrayView< localIndex const > const & faceSet = faceSetGroup.getReference< SortedArray< localIndex > >( faceSetName ); - SurfaceElementRegion & faceRegion = elemManager.getRegion< SurfaceElementRegion >( faceSetName ); - - for( localIndex const faceIndex : faceSet ) - { - localIndex const faceIndices[2] = { faceIndex, faceIndex }; - faceRegion.addToSurfaceMesh( &faceManager, faceIndices ); - } - - FaceElementSubRegion const & faceSubRegion = faceRegion.getUniqueSubRegion< FaceElementSubRegion >(); - FixedToManyElementRelation const & faceElementsToCells = faceSubRegion.getToCellRelation(); - - std::function< std::tuple< CellElementSubRegion *, CellElementSubRegion * >(localIndex) > getSubregions = [&]( localIndex surfaceSubRegionIndex ) -> std::tuple< CellElementSubRegion *, - CellElementSubRegion * > - { - - int regionIdx0 = faceElementsToCells.m_toElementRegion[surfaceSubRegionIndex][0]; - int regionIdx1 = faceElementsToCells.m_toElementRegion[surfaceSubRegionIndex][1]; - int subRegionIdx0 = faceElementsToCells.m_toElementSubRegion[surfaceSubRegionIndex][0]; - int subRegionIdx1 = faceElementsToCells.m_toElementSubRegion[surfaceSubRegionIndex][1]; - - CellElementRegion & region0 = elemManager.getRegion< CellElementRegion >( regionIdx0 ); - CellElementRegion & region1 = elemManager.getRegion< CellElementRegion >( regionIdx1 ); - - CellElementSubRegion * subRegion0 = ®ion0.getSubRegion< CellElementSubRegion >( subRegionIdx0 ); - CellElementSubRegion * subRegion1 = ®ion1.getSubRegion< CellElementSubRegion >( subRegionIdx1 ); - return std::make_tuple( subRegion0, subRegion1 ); - }; - + +namespace geos +{ + +using namespace dataRepository; +using namespace constitutive; +using namespace fields::immiscibleMultiphaseFlow; +using namespace immiscibleMultiphaseKernels; + + +ImmiscibleMultiphaseFlow::ImmiscibleMultiphaseFlow( const string & name, + Group * const parent ) + : + FlowSolverBase( name, parent ), + m_numPhases( 2 ), + m_hasCapPressure( false ), + m_useTotalMassEquation ( 1 ) +{ + this->registerWrapper( viewKeyStruct::inputTemperatureString(), &m_inputTemperature ). + setInputFlag( InputFlags::REQUIRED ). + setDescription( "Temperature" ); + + this->registerWrapper( viewKeyStruct::useTotalMassEquationString(), &m_useTotalMassEquation ). + setSizedFromParent( 0 ). + setInputFlag( InputFlags::OPTIONAL ). + setApplyDefaultValue( 1 ). + setDescription( "Flag indicating whether total mass equation is used" ); + + this->registerWrapper( viewKeyStruct::gravityDensitySchemeString(), &m_gravityDensityScheme ). + setSizedFromParent( 0 ). + setInputFlag( InputFlags::OPTIONAL ). + setApplyDefaultValue( GravityDensityScheme::ArithmeticAverage ). + setDescription( "Scheme for density treatment in gravity" ); + + this->registerWrapper( viewKeyStruct::solutionChangeScalingFactorString(), &m_solutionChangeScalingFactor ). + setSizedFromParent( 0 ). + setInputFlag( InputFlags::OPTIONAL ). + setApplyDefaultValue( 0.5 ). + setDescription( "Damping factor for solution change targets" ); + this->registerWrapper( viewKeyStruct::targetRelativePresChangeString(), &m_targetRelativePresChange ). + setSizedFromParent( 0 ). + setInputFlag( InputFlags::OPTIONAL ). + setApplyDefaultValue( 0.2 ). + setDescription( "Target (relative) change in pressure in a time step (expected value between 0 and 1)" ); + this->registerWrapper( viewKeyStruct::targetPhaseVolFracChangeString(), &m_targetPhaseVolFracChange ). + setSizedFromParent( 0 ). + setInputFlag( InputFlags::OPTIONAL ). + setApplyDefaultValue( 0.2 ). + setDescription( "Target (absolute) change in phase volume fraction in a time step" ); + + this->registerWrapper( viewKeyStruct::interfaceFaceSetNamesString(), + &m_interfaceFaceSetNames ). + setInputFlag( InputFlags::OPTIONAL ). + setDescription( "Names of the interface face sets" ); +} + +void ImmiscibleMultiphaseFlow::postInputInitialization() +{ + FlowSolverBase::postInputInitialization(); +} + +void ImmiscibleMultiphaseFlow::registerDataOnMesh( Group & meshBodies ) +{ + FlowSolverBase::registerDataOnMesh( meshBodies ); + + // 0. Find a "reference" fluid model name (at this point, models are already attached to subregions) + forDiscretizationOnMeshTargets( meshBodies, [&]( string const &, + MeshLevel & mesh, + string_array const & regionNames ) + { + mesh.getElemManager().forElementSubRegions( regionNames, + [&]( localIndex const, + ElementSubRegionBase & subRegion ) + { + // If at least one region has a capillary pressure model, consider it enabled for all + string const capPresName = getConstitutiveName< CapillaryPressureBase >( subRegion ); + if( !capPresName.empty() ) + { + m_hasCapPressure = true; + } + } ); + } ); + + m_numDofPerCell = m_numPhases; + + // 2. Register and resize all fields as necessary + forDiscretizationOnMeshTargets( meshBodies, [&]( string const &, + MeshLevel & mesh, + string_array const & regionNames ) + { + mesh.getElemManager().forElementSubRegions( regionNames, + [&]( localIndex const, + ElementSubRegionBase & subRegion ) + { + if( m_hasCapPressure ) + { + subRegion.registerWrapper< string >( viewKeyStruct::capPressureNamesString() ). + setPlotLevel( PlotLevel::NOPLOT ). + setRestartFlags( RestartFlags::NO_WRITE ). + setSizedFromParent( 0 ). + setDescription( "Name of the capillary pressure constitutive model to use" ). + reference(); + + string & capPresName = subRegion.getReference< string >( viewKeyStruct::capPressureNamesString() ); + capPresName = getConstitutiveName< CapillaryPressureBase >( subRegion ); + GEOS_THROW_IF( capPresName.empty(), + GEOS_FMT( "{}: Capillary pressure model not found on subregion {}", + getDataContext(), subRegion.getDataContext() ), + InputError ); + } + + // The resizing of the arrays needs to happen here, before the call to initializePreSubGroups, + // to make sure that the dimensions are properly set before the timeHistoryOutput starts its initialization. + subRegion.registerField< phaseVolumeFraction >( getName() ). + reference().resizeDimension< 1 >( m_numPhases ); + + subRegion.registerField< phaseVolumeFraction_n >( getName() ). + reference().resizeDimension< 1 >( m_numPhases ); + + subRegion.registerField< bcPhaseVolumeFraction >( getName() ). + reference().resizeDimension< 1 >( m_numPhases ); + + subRegion.registerField< phaseMass >( getName() ). + reference().resizeDimension< 1 >( m_numPhases ); + + subRegion.registerField< phaseMass_n >( getName() ). + reference().resizeDimension< 1 >( m_numPhases ); + + subRegion.registerField< phaseMobility >( getName() ). + reference().resizeDimension< 1 >( m_numPhases ); + + subRegion.registerField< dPhaseMobility >( getName() ). + reference().resizeDimension< 1, 2 >( m_numPhases, m_numPhases ); // dP, dS + + } ); + + } ); +} + +void ImmiscibleMultiphaseFlow::setConstitutiveNames( ElementSubRegionBase & subRegion ) const +{ + setConstitutiveName< TwoPhaseImmiscibleFluid >( subRegion, viewKeyStruct::fluidNamesString(), "two phase immiscible fluid" ); + + setConstitutiveName< RelativePermeabilityBase >( subRegion, viewKeyStruct::relPermNamesString(), "relative permeability" ); +} + +void ImmiscibleMultiphaseFlow::initializePreSubGroups() +{ + m_linearSolverParameters.get().mgr.strategy = LinearSolverParameters::MGR::StrategyType::immiscibleMultiphaseFVM; + + FlowSolverBase::initializePreSubGroups(); + + DomainPartition & domain = this->getGroupByPath< DomainPartition >( "/Problem/domain" ); + + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, + MeshLevel & mesh, + string_array const & regionNames ) + { + mesh.getElemManager().forElementSubRegions( regionNames, + [&]( localIndex const, + ElementSubRegionBase & subRegion ) + { + arrayView1d< real64 > const temp = subRegion.getField< fields::flow::temperature >(); + temp.setValues< parallelHostPolicy >( m_inputTemperature ); + } ); + } ); + + // ***** Create FaceElements ***** + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, + MeshLevel & meshLevel, + string_array const & GEOS_UNUSED_PARAM( regionNames )) + { + + FaceManager const & faceManager = meshLevel.getFaceManager(); + Group const & faceSetGroup = faceManager.sets(); + ElementRegionManager & elemManager = meshLevel.getElemManager(); + m_interfaceConstitutivePairs.resize( m_interfaceFaceSetNames.size() ); + + // this is the FaceElement Level + for( size_t surfaceRegionIndex=0; surfaceRegionIndex < m_interfaceFaceSetNames.size(); ++surfaceRegionIndex ) + { + string const & faceSetName = m_interfaceFaceSetNames[surfaceRegionIndex]; + SortedArrayView< localIndex const > const & faceSet = faceSetGroup.getReference< SortedArray< localIndex > >( faceSetName ); + SurfaceElementRegion & faceRegion = elemManager.getRegion< SurfaceElementRegion >( faceSetName ); + + for( localIndex const faceIndex : faceSet ) + { + localIndex const faceIndices[2] = { faceIndex, faceIndex }; + faceRegion.addToSurfaceMesh( &faceManager, faceIndices ); + } + + FaceElementSubRegion const & faceSubRegion = faceRegion.getUniqueSubRegion< FaceElementSubRegion >(); + FixedToManyElementRelation const & faceElementsToCells = faceSubRegion.getToCellRelation(); + + std::function< std::tuple< CellElementSubRegion *, CellElementSubRegion * >(localIndex) > getSubregions = [&]( localIndex surfaceSubRegionIndex ) -> std::tuple< CellElementSubRegion *, + CellElementSubRegion * > + { + + int regionIdx0 = faceElementsToCells.m_toElementRegion[surfaceSubRegionIndex][0]; + int regionIdx1 = faceElementsToCells.m_toElementRegion[surfaceSubRegionIndex][1]; + int subRegionIdx0 = faceElementsToCells.m_toElementSubRegion[surfaceSubRegionIndex][0]; + int subRegionIdx1 = faceElementsToCells.m_toElementSubRegion[surfaceSubRegionIndex][1]; + + CellElementRegion & region0 = elemManager.getRegion< CellElementRegion >( regionIdx0 ); + CellElementRegion & region1 = elemManager.getRegion< CellElementRegion >( regionIdx1 ); + + CellElementSubRegion * subRegion0 = ®ion0.getSubRegion< CellElementSubRegion >( subRegionIdx0 ); + CellElementSubRegion * subRegion1 = ®ion1.getSubRegion< CellElementSubRegion >( subRegionIdx1 ); + return std::make_tuple( subRegion0, subRegion1 ); + }; + // std::tuple< CellElementSubRegion *, CellElementSubRegion * > subRegionPair = getSubregions( surfaceRegionIndex ); // CellElementSubRegion * subRegion0 = std::get< 0 >( subRegionPair ); // CellElementSubRegion * subRegion1 = std::get< 1 >( subRegionPair ); - + // // get constitutives by type and name: relPerms, capPressures, Fluids (three pointers) // std::string & relPermName0 = subRegion0->getReference< std::string >( viewKeyStruct::relPermNamesString()); // std::string & relPermName1 = subRegion1->getReference< std::string >( viewKeyStruct::relPermNamesString()); // RelativePermeabilityBase * relPerm0 = &getConstitutiveModel< RelativePermeabilityBase >( *subRegion0, relPermName0 ); // RelativePermeabilityBase * relPerm1 = &getConstitutiveModel< RelativePermeabilityBase >( *subRegion1, relPermName1 ); - + // std::string & cappresName0 = subRegion0->getReference< std::string >( viewKeyStruct::capPressureNamesString()); // std::string & cappresName1 = subRegion1->getReference< std::string >( viewKeyStruct::capPressureNamesString()); // CapillaryPressureBase * capPressure0 = &getConstitutiveModel< CapillaryPressureBase >( *subRegion0, cappresName0 ); // CapillaryPressureBase * capPressure1 = &getConstitutiveModel< CapillaryPressureBase >( *subRegion1, cappresName1 ); - + // std::string & fluidName0 = subRegion0->getReference< std::string >( viewKeyStruct::fluidNamesString() ); // std::string & fluidName1 = subRegion1->getReference< std::string >( viewKeyStruct::fluidNamesString() ); - + // TwoPhaseImmiscibleFluid * fluid0 = &getConstitutiveModel< TwoPhaseImmiscibleFluid >( *subRegion0, fluidName0 ); // TwoPhaseImmiscibleFluid * fluid1 = &getConstitutiveModel< TwoPhaseImmiscibleFluid >( *subRegion1, fluidName1 ); - + // m_interfaceConstitutivePairs[surfaceRegionIndex][0] = std::make_tuple( relPerm0, capPressure0, fluid0 ); // m_interfaceConstitutivePairs[surfaceRegionIndex][1] = std::make_tuple( relPerm1, capPressure1, fluid1 ); - // Find a representative face element in this surface region with two adjacent cells -localIndex fei = -1; + // Find a representative face element in this surface region with two adjacent cells + localIndex fei = -1; // Prefer face element 0 if valid; otherwise scan -if( faceElementsToCells.size() > 0 ) + if( faceElementsToCells.size() > 0 ) + { + // Check if face element 0 has two adjacent cells + if( faceElementsToCells.m_toElementRegion[0].size() >= 2 ) + { + fei = 0; + } + else + { + // Scan to find the first interior face element with two neighbors + for( localIndex i = 1; i < faceElementsToCells.size(); ++i ) + { + if( faceElementsToCells.m_toElementRegion[i].size() >= 2 ) + { + fei = i; + break; + } + } + } + } + +// If no valid face element, skip this surface region + if( fei < 0 ) + { + continue; + } + + std::tuple< CellElementSubRegion *, CellElementSubRegion * > subRegionPair = getSubregions( fei ); + CellElementSubRegion * subRegion0 = std::get< 0 >( subRegionPair ); + CellElementSubRegion * subRegion1 = std::get< 1 >( subRegionPair ); + +// get constitutives by type and name: relPerms, capPressures, Fluids (three pointers) + std::string & relPermName0 = subRegion0->getReference< std::string >( viewKeyStruct::relPermNamesString()); + std::string & relPermName1 = subRegion1->getReference< std::string >( viewKeyStruct::relPermNamesString()); + RelativePermeabilityBase * relPerm0 = &getConstitutiveModel< RelativePermeabilityBase >( *subRegion0, relPermName0 ); + RelativePermeabilityBase * relPerm1 = &getConstitutiveModel< RelativePermeabilityBase >( *subRegion1, relPermName1 ); + + std::string & cappresName0 = subRegion0->getReference< std::string >( viewKeyStruct::capPressureNamesString()); + std::string & cappresName1 = subRegion1->getReference< std::string >( viewKeyStruct::capPressureNamesString()); + CapillaryPressureBase * capPressure0 = &getConstitutiveModel< CapillaryPressureBase >( *subRegion0, cappresName0 ); + CapillaryPressureBase * capPressure1 = &getConstitutiveModel< CapillaryPressureBase >( *subRegion1, cappresName1 ); + + std::string & fluidName0 = subRegion0->getReference< std::string >( viewKeyStruct::fluidNamesString() ); + std::string & fluidName1 = subRegion1->getReference< std::string >( viewKeyStruct::fluidNamesString() ); + + TwoPhaseImmiscibleFluid * fluid0 = &getConstitutiveModel< TwoPhaseImmiscibleFluid >( *subRegion0, fluidName0 ); + TwoPhaseImmiscibleFluid * fluid1 = &getConstitutiveModel< TwoPhaseImmiscibleFluid >( *subRegion1, fluidName1 ); + + m_interfaceConstitutivePairs[surfaceRegionIndex][0] = std::make_tuple( relPerm0, capPressure0, fluid0 ); + m_interfaceConstitutivePairs[surfaceRegionIndex][1] = std::make_tuple( relPerm1, capPressure1, fluid1 ); + + } + } ); + +} + + +void ImmiscibleMultiphaseFlow::updateFluidModel( ObjectManagerBase & dataGroup ) const { - // Check if face element 0 has two adjacent cells - if( faceElementsToCells.m_toElementRegion[0].size() >= 2 ) + GEOS_MARK_FUNCTION; + + arrayView1d< real64 const > const pres = dataGroup.getField< fields::flow::pressure >(); + + TwoPhaseImmiscibleFluid & fluid = getConstitutiveModel< TwoPhaseImmiscibleFluid >( dataGroup, dataGroup.getReference< string >( viewKeyStruct::fluidNamesString() ) ); + + constitutiveUpdatePassThru( fluid, [&] ( auto & castedFluid ) { - fei = 0; + using FluidType = TYPEOFREF( castedFluid ); + typename FluidType::KernelWrapper fluidWrapper = castedFluid.createKernelWrapper(); + + FluidUpdateKernel::launch< parallelDevicePolicy<> >( dataGroup.size(), fluidWrapper, pres ); + } ); +} + + +void ImmiscibleMultiphaseFlow::updateRelPermModel( ObjectManagerBase & dataGroup ) const +{ + GEOS_MARK_FUNCTION; + + + GEOS_UNUSED_VAR( dataGroup ); + + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFrac = + dataGroup.getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); + + string const & relPermName = dataGroup.getReference< string >( viewKeyStruct::relPermNamesString() ); + RelativePermeabilityBase & relPerm = getConstitutiveModel< RelativePermeabilityBase >( dataGroup, relPermName ); + + constitutive::constitutiveUpdatePassThru( relPerm, [&] ( auto & castedRelPerm ) + { + typename TYPEOFREF( castedRelPerm ) ::KernelWrapper relPermWrapper = castedRelPerm.createKernelWrapper(); + + isothermalCompositionalMultiphaseBaseKernels:: + RelativePermeabilityUpdateKernel:: + launch< parallelDevicePolicy<> >( dataGroup.size(), + relPermWrapper, + phaseVolFrac ); + } ); +} + +void ImmiscibleMultiphaseFlow::updateCapPressureModel( ObjectManagerBase & dataGroup ) const +{ + GEOS_MARK_FUNCTION; + + if( m_hasCapPressure ) + { + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFrac = + dataGroup.getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); + + string const & cappresName = dataGroup.getReference< string >( viewKeyStruct::capPressureNamesString() ); + CapillaryPressureBase & capPressure = getConstitutiveModel< CapillaryPressureBase >( dataGroup, cappresName ); + + constitutive::constitutiveUpdatePassThru( capPressure, [&] ( auto & castedCapPres ) + { + typename TYPEOFREF( castedCapPres ) ::KernelWrapper capPresWrapper = castedCapPres.createKernelWrapper(); + + // isothermalCompositionalMultiphaseBaseKernels:: + immiscibleMultiphaseKernels:: + CapillaryPressureUpdateKernel:: + launch< parallelDevicePolicy<> >( dataGroup.size(), + capPresWrapper, + phaseVolFrac ); + } ); } - else +} + + +void ImmiscibleMultiphaseFlow::updateFluidState( ElementSubRegionBase & subRegion ) const +{ + GEOS_MARK_FUNCTION; + + updateFluidModel( subRegion ); + updateVolumeConstraint( subRegion ); + updatePhaseMass( subRegion ); + updateRelPermModel( subRegion ); + updatePhaseMobility( subRegion ); + updateCapPressureModel( subRegion ); +} + + +void ImmiscibleMultiphaseFlow::updatePhaseMass( ElementSubRegionBase & subRegion ) const +{ + GEOS_MARK_FUNCTION; + + string const & solidName = subRegion.getReference< string >( viewKeyStruct::solidNamesString() ); + string const & fluidName = subRegion.getReference< string >( viewKeyStruct::fluidNamesString() ); + + TwoPhaseImmiscibleFluid const & fluid = getConstitutiveModel< TwoPhaseImmiscibleFluid >( subRegion, fluidName ); + CoupledSolidBase const & solid = getConstitutiveModel< CoupledSolidBase >( subRegion, solidName ); + + arrayView1d< real64 const > const volume = subRegion.getElementVolume(); + arrayView2d< real64 const > const porosity = solid.getPorosity(); + + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFrac= subRegion.getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); + arrayView3d< real64 const, multifluid::USD_PHASE > phaseDens = fluid.phaseDensity(); + arrayView2d< real64, immiscibleFlow::USD_PHASE > const phaseMass = subRegion.getField< fields::immiscibleMultiphaseFlow::phaseMass >(); + + // Might be needed for geomechanics????? if so, need to change the accumulation as well? + //arrayView1d< real64 > const deltaVolume = subRegion.getField< fields::flow::deltaVolume >(); + + forAll< parallelDevicePolicy<> >( subRegion.size(), [=] GEOS_HOST_DEVICE ( localIndex const ei ) + { + real64 const poreVolume = volume[ei] * porosity[ei][0]; + for( integer ip = 0; ip < 2; ++ip ) + { + phaseMass[ei][ip] = poreVolume * phaseVolFrac[ei][ip] * phaseDens[ei][0][ip]; + } + } ); +} + + +void ImmiscibleMultiphaseFlow::updatePhaseMobility( ObjectManagerBase & dataGroup ) const +{ + GEOS_MARK_FUNCTION; + + // note that the phase mobility computed here also includes phase density + string const & fluidName = dataGroup.getReference< string >( viewKeyStruct::fluidNamesString() ); + TwoPhaseImmiscibleFluid const & fluid = getConstitutiveModel< TwoPhaseImmiscibleFluid >( dataGroup, fluidName ); + + string const & relpermName = dataGroup.getReference< string >( viewKeyStruct::relPermNamesString() ); + RelativePermeabilityBase const & relperm = getConstitutiveModel< RelativePermeabilityBase >( dataGroup, relpermName ); + + immiscibleMultiphaseKernels:: + PhaseMobilityKernelFactory:: + createAndLaunch< parallelDevicePolicy<> >( m_numPhases, + dataGroup, + fluid, + relperm ); +} + +void ImmiscibleMultiphaseFlow::initializeFluidState( MeshLevel & mesh, + string_array const & regionNames ) +{ + GEOS_MARK_FUNCTION; + + mesh.getElemManager().forElementSubRegions( regionNames, + [&]( localIndex const, + ElementSubRegionBase & subRegion ) + { + // 2. Assume global component fractions have been prescribed. + // Initialize constitutive state to get fluid density. + updateFluidModel( subRegion ); + + } ); + + // for some reason CUDA does not want the host_device lambda to be defined inside the generic lambda + // I need the exact type of the subRegion for updateSolidflowProperties to work well. + mesh.getElemManager().forElementSubRegions< CellElementSubRegion, + SurfaceElementSubRegion >( regionNames, [&]( localIndex const, + auto & subRegion ) + { + // 4. Initialize/update dependent state quantities + + // 4.1 Update the constitutive models that only depend on + // - the primary variables + // - the fluid constitutive quantities (as they have already been updated) + // We postpone the other constitutive models for now + // In addition, to avoid multiplying permeability/porosity bay netToGross in the assembly kernel, we do it once and for all here + arrayView1d< real64 const > const netToGross = subRegion.template getField< fields::flow::netToGross >(); + CoupledSolidBase const & porousSolid = + getConstitutiveModel< CoupledSolidBase >( subRegion, subRegion.template getReference< string >( viewKeyStruct::solidNamesString() ) ); + PermeabilityBase const & permeabilityModel = + getConstitutiveModel< PermeabilityBase >( subRegion, subRegion.template getReference< string >( viewKeyStruct::permeabilityNamesString() ) ); + permeabilityModel.scaleHorizontalPermeability( netToGross ); + porousSolid.scaleReferencePorosity( netToGross ); + saveConvergedState( subRegion ); // necessary for a meaningful porosity update in sequential schemes + updatePorosityAndPermeability( subRegion ); + + // Now, we initialize and update each constitutive model one by one + + // 4.2 Save the computed porosity into the old porosity + // + // Note: + // - This must be called after updatePorosityAndPermeability + // - This step depends on porosity + string const & solidName = subRegion.template getReference< string >( viewKeyStruct::solidNamesString() ); + CoupledSolidBase const & porousMaterial = getConstitutiveModel< CoupledSolidBase >( subRegion, solidName ); + porousMaterial.initializeState(); + + // 4.3 Initialize/update the relative permeability model using the initial phase volume fraction + // This is needed to handle relative permeability hysteresis + // Also, initialize the fluid model + // + // Note: + // - This must be called after updateVolumeConstraint + // - This step depends on phaseVolFraction + + // initialized phase volume fraction + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFrac = + subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); + + string const & relpermName = subRegion.template getReference< string >( viewKeyStruct::relPermNamesString() ); + RelativePermeabilityBase & relPermMaterial = + getConstitutiveModel< RelativePermeabilityBase >( subRegion, relpermName ); + relPermMaterial.saveConvergedPhaseVolFractionState( phaseVolFrac ); // this needs to happen before calling updateRelPermModel + updateRelPermModel( subRegion ); + relPermMaterial.saveConvergedState(); // this needs to happen after calling updateRelPermModel + + // 4.4 Then, we initialize/update the capillary pressure model + // + // Note: + // - This must be called after updatePorosityAndPermeability + // - This step depends on porosity and permeability + if( m_hasCapPressure ) + { + // initialized porosity + arrayView2d< real64 const > const porosity = porousMaterial.getPorosity(); + + string const & permName = subRegion.template getReference< string >( viewKeyStruct::permeabilityNamesString() ); + PermeabilityBase const & permeabilityMaterial = getConstitutiveModel< PermeabilityBase >( subRegion, permName ); + // initialized permeability + arrayView3d< real64 const > const permeability = permeabilityMaterial.permeability(); + + string const & capPressureName = subRegion.template getReference< string >( viewKeyStruct::capPressureNamesString() ); + CapillaryPressureBase const & capPressureMaterial = + getConstitutiveModel< CapillaryPressureBase >( subRegion, capPressureName ); + capPressureMaterial.initializeRockState( porosity, permeability ); // this needs to happen before calling updateCapPressureModel + updateCapPressureModel( subRegion ); + } + + // 4.5 Update the phase mobility + // + // Note: + // - This must be called after updateRelPermModel + // - This step depends phaseRelPerm + updatePhaseMobility( subRegion ); + + } ); + + // 5. Save initial pressure + mesh.getElemManager().forElementSubRegions( regionNames, [&]( localIndex const, + ElementSubRegionBase & subRegion ) + { + arrayView1d< real64 const > const pres = subRegion.getField< fields::flow::pressure >(); + arrayView1d< real64 > const initPres = subRegion.getField< fields::flow::initialPressure >(); + arrayView1d< real64 const > const temp = subRegion.getField< fields::flow::temperature >(); + arrayView1d< real64 > const initTemp = subRegion.template getField< fields::flow::initialTemperature >(); + initPres.setValues< parallelDevicePolicy<> >( pres ); + initTemp.setValues< parallelDevicePolicy<> >( temp ); + + // TODO: Missing updatePhaseMass? + } ); +} + + +void ImmiscibleMultiphaseFlow::initializePostInitialConditionsPreSubGroups() +{ + GEOS_MARK_FUNCTION; + + FlowSolverBase::initializePostInitialConditionsPreSubGroups(); + + DomainPartition & domain = this->getGroupByPath< DomainPartition >( "/Problem/domain" ); + + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, + MeshLevel & mesh, + string_array const & regionNames ) + { + FieldIdentifiers fieldsToBeSync; + fieldsToBeSync.addElementFields( { fields::flow::pressure::key(), + fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key() }, + regionNames ); + + CommunicationTools::getInstance().synchronizeFields( fieldsToBeSync, mesh, domain.getNeighbors(), false ); + } ); + + // Retrieve the numerical methods and finite volume manager + FiniteVolumeManager const & fvManager = domain.getNumericalMethodManager().getFiniteVolumeManager(); + FluxApproximationBase const & fluxApprox = fvManager.getFluxApproximation( m_discretizationName ); + const geos::string flux_approximation_name = fluxApprox.getName(); + + // Clear the existing mapping between connector indices and interface region indices + m_interfaceRegionByConnector.clear(); + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( std::string const &, + MeshLevel & meshLevel, + string_array const & GEOS_UNUSED_PARAM( regionNames )) { - // Scan to find the first interior face element with two neighbors - for( localIndex i = 1; i < faceElementsToCells.size(); ++i ) + // Access the face manager and retrieve the face set group for the current mesh level + FaceManager const & faceManager = meshLevel.getFaceManager(); + Group const & faceSetGroup = faceManager.sets(); + + // Access the connector indices map (face index → connector index) + Group & stencilGroup = + meshLevel.getGroup( FluxApproximationBase::groupKeyStruct::stencilMeshGroupString()) + .getGroup( flux_approximation_name ); + CellElementStencilTPFA & stencil = + stencilGroup.getReference< CellElementStencilTPFA >( + FluxApproximationBase::viewKeyStruct::cellStencilString()); + unordered_map< localIndex, localIndex > const & connectorIndices = stencil.getConnectorIndices(); + + // for all interface face sets to map connector indices to their corresponding interface region indices + for( size_t surfaceRegionIndex = 0; surfaceRegionIndex < m_interfaceFaceSetNames.size(); ++surfaceRegionIndex ) { - if( faceElementsToCells.m_toElementRegion[i].size() >= 2 ) + // Iterate over each face and associate its connector index + std::string const & faceSetName = m_interfaceFaceSetNames[surfaceRegionIndex]; + for( localIndex kf : faceSetGroup.getReference< SortedArray< localIndex > >( faceSetName )) { - fei = i; - break; + auto it = connectorIndices.find( kf ); + if( it != connectorIndices.end()) + { + // Map the connector index to the corresponding surface region index + m_interfaceRegionByConnector[it->second] = surfaceRegionIndex; + } } } - } + } ); + + + initializeState( domain ); } -// If no valid face element, skip this surface region -if( fei < 0 ) + +void +ImmiscibleMultiphaseFlow::implicitStepSetup( real64 const & GEOS_UNUSED_PARAM( time_n ), + real64 const & GEOS_UNUSED_PARAM( dt ), + DomainPartition & domain ) { - continue; + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, + MeshLevel & mesh, + string_array const & regionNames ) + { + mesh.getElemManager().forElementSubRegions< CellElementSubRegion, + SurfaceElementSubRegion >( regionNames, + [&]( localIndex const, + auto & subRegion ) + { + saveConvergedState( subRegion ); + + // update porosity, permeability + updatePorosityAndPermeability( subRegion ); + // update all fluid properties + updateVolumeConstraint( subRegion ); + updateFluidState( subRegion ); + + // after the update, save the new saturation + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFrac = + subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); + + arrayView2d< real64, immiscibleFlow::USD_PHASE > const phaseVolFrac_n = + subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction_n >(); + phaseVolFrac_n.setValues< parallelDevicePolicy<> >( phaseVolFrac ); + + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const & phaseMass = + subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseMass >(); + + arrayView2d< real64, immiscibleFlow::USD_PHASE > const & phaseMass_n = + subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseMass_n >(); + phaseMass_n.setValues< parallelDevicePolicy<> >( phaseMass ); + + } ); + } ); } -std::tuple< CellElementSubRegion *, CellElementSubRegion * > subRegionPair = getSubregions( fei ); -CellElementSubRegion * subRegion0 = std::get< 0 >( subRegionPair ); -CellElementSubRegion * subRegion1 = std::get< 1 >( subRegionPair ); +void ImmiscibleMultiphaseFlow::assembleSystem( real64 const GEOS_UNUSED_PARAM( time_n ), + real64 const dt, + DomainPartition & domain, + DofManager const & dofManager, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) +{ + GEOS_MARK_FUNCTION; -// get constitutives by type and name: relPerms, capPressures, Fluids (three pointers) -std::string & relPermName0 = subRegion0->getReference< std::string >( viewKeyStruct::relPermNamesString()); -std::string & relPermName1 = subRegion1->getReference< std::string >( viewKeyStruct::relPermNamesString()); -RelativePermeabilityBase * relPerm0 = &getConstitutiveModel< RelativePermeabilityBase >( *subRegion0, relPermName0 ); -RelativePermeabilityBase * relPerm1 = &getConstitutiveModel< RelativePermeabilityBase >( *subRegion1, relPermName1 ); - -std::string & cappresName0 = subRegion0->getReference< std::string >( viewKeyStruct::capPressureNamesString()); -std::string & cappresName1 = subRegion1->getReference< std::string >( viewKeyStruct::capPressureNamesString()); -CapillaryPressureBase * capPressure0 = &getConstitutiveModel< CapillaryPressureBase >( *subRegion0, cappresName0 ); -CapillaryPressureBase * capPressure1 = &getConstitutiveModel< CapillaryPressureBase >( *subRegion1, cappresName1 ); - -std::string & fluidName0 = subRegion0->getReference< std::string >( viewKeyStruct::fluidNamesString() ); -std::string & fluidName1 = subRegion1->getReference< std::string >( viewKeyStruct::fluidNamesString() ); - -TwoPhaseImmiscibleFluid * fluid0 = &getConstitutiveModel< TwoPhaseImmiscibleFluid >( *subRegion0, fluidName0 ); -TwoPhaseImmiscibleFluid * fluid1 = &getConstitutiveModel< TwoPhaseImmiscibleFluid >( *subRegion1, fluidName1 ); - -m_interfaceConstitutivePairs[surfaceRegionIndex][0] = std::make_tuple( relPerm0, capPressure0, fluid0 ); -m_interfaceConstitutivePairs[surfaceRegionIndex][1] = std::make_tuple( relPerm1, capPressure1, fluid1 ); - - } - } ); - - } - - - void ImmiscibleMultiphaseFlow::updateFluidModel( ObjectManagerBase & dataGroup ) const - { - GEOS_MARK_FUNCTION; - - arrayView1d< real64 const > const pres = dataGroup.getField< fields::flow::pressure >(); - - TwoPhaseImmiscibleFluid & fluid = getConstitutiveModel< TwoPhaseImmiscibleFluid >( dataGroup, dataGroup.getReference< string >( viewKeyStruct::fluidNamesString() ) ); - - constitutiveUpdatePassThru( fluid, [&] ( auto & castedFluid ) - { - using FluidType = TYPEOFREF( castedFluid ); - typename FluidType::KernelWrapper fluidWrapper = castedFluid.createKernelWrapper(); - - FluidUpdateKernel::launch< parallelDevicePolicy<> >( dataGroup.size(), fluidWrapper, pres ); - } ); - } - - - void ImmiscibleMultiphaseFlow::updateRelPermModel( ObjectManagerBase & dataGroup ) const - { - GEOS_MARK_FUNCTION; - - - GEOS_UNUSED_VAR( dataGroup ); - - arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFrac = - dataGroup.getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); - - string const & relPermName = dataGroup.getReference< string >( viewKeyStruct::relPermNamesString() ); - RelativePermeabilityBase & relPerm = getConstitutiveModel< RelativePermeabilityBase >( dataGroup, relPermName ); - - constitutive::constitutiveUpdatePassThru( relPerm, [&] ( auto & castedRelPerm ) - { - typename TYPEOFREF( castedRelPerm ) ::KernelWrapper relPermWrapper = castedRelPerm.createKernelWrapper(); - - isothermalCompositionalMultiphaseBaseKernels:: - RelativePermeabilityUpdateKernel:: - launch< parallelDevicePolicy<> >( dataGroup.size(), - relPermWrapper, - phaseVolFrac ); - } ); - } - - void ImmiscibleMultiphaseFlow::updateCapPressureModel( ObjectManagerBase & dataGroup ) const - { - GEOS_MARK_FUNCTION; - - if( m_hasCapPressure ) - { - arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFrac = - dataGroup.getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); - - string const & cappresName = dataGroup.getReference< string >( viewKeyStruct::capPressureNamesString() ); - CapillaryPressureBase & capPressure = getConstitutiveModel< CapillaryPressureBase >( dataGroup, cappresName ); - - constitutive::constitutiveUpdatePassThru( capPressure, [&] ( auto & castedCapPres ) - { - typename TYPEOFREF( castedCapPres ) ::KernelWrapper capPresWrapper = castedCapPres.createKernelWrapper(); - - // isothermalCompositionalMultiphaseBaseKernels:: - immiscibleMultiphaseKernels:: - CapillaryPressureUpdateKernel:: - launch< parallelDevicePolicy<> >( dataGroup.size(), - capPresWrapper, - phaseVolFrac ); - } ); - } - } - - - void ImmiscibleMultiphaseFlow::updateFluidState( ElementSubRegionBase & subRegion ) const - { - GEOS_MARK_FUNCTION; - - updateFluidModel( subRegion ); - updateVolumeConstraint( subRegion ); - updatePhaseMass( subRegion ); - updateRelPermModel( subRegion ); - updatePhaseMobility( subRegion ); - updateCapPressureModel( subRegion ); - } - - - void ImmiscibleMultiphaseFlow::updatePhaseMass( ElementSubRegionBase & subRegion ) const - { - GEOS_MARK_FUNCTION; - - string const & solidName = subRegion.getReference< string >( viewKeyStruct::solidNamesString() ); - string const & fluidName = subRegion.getReference< string >( viewKeyStruct::fluidNamesString() ); - - TwoPhaseImmiscibleFluid const & fluid = getConstitutiveModel< TwoPhaseImmiscibleFluid >( subRegion, fluidName ); - CoupledSolidBase const & solid = getConstitutiveModel< CoupledSolidBase >( subRegion, solidName ); - - arrayView1d< real64 const > const volume = subRegion.getElementVolume(); - arrayView2d< real64 const > const porosity = solid.getPorosity(); - - arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFrac= subRegion.getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); - arrayView3d< real64 const, multifluid::USD_PHASE > phaseDens = fluid.phaseDensity(); - arrayView2d< real64, immiscibleFlow::USD_PHASE > const phaseMass = subRegion.getField< fields::immiscibleMultiphaseFlow::phaseMass >(); - - // Might be needed for geomechanics????? if so, need to change the accumulation as well? - //arrayView1d< real64 > const deltaVolume = subRegion.getField< fields::flow::deltaVolume >(); - - forAll< parallelDevicePolicy<> >( subRegion.size(), [=] GEOS_HOST_DEVICE ( localIndex const ei ) - { - real64 const poreVolume = volume[ei] * porosity[ei][0]; - for( integer ip = 0; ip < 2; ++ip ) - { - phaseMass[ei][ip] = poreVolume * phaseVolFrac[ei][ip] * phaseDens[ei][0][ip]; - } - } ); - } - - - void ImmiscibleMultiphaseFlow::updatePhaseMobility( ObjectManagerBase & dataGroup ) const - { - GEOS_MARK_FUNCTION; - - // note that the phase mobility computed here also includes phase density - string const & fluidName = dataGroup.getReference< string >( viewKeyStruct::fluidNamesString() ); - TwoPhaseImmiscibleFluid const & fluid = getConstitutiveModel< TwoPhaseImmiscibleFluid >( dataGroup, fluidName ); - - string const & relpermName = dataGroup.getReference< string >( viewKeyStruct::relPermNamesString() ); - RelativePermeabilityBase const & relperm = getConstitutiveModel< RelativePermeabilityBase >( dataGroup, relpermName ); - - immiscibleMultiphaseKernels:: - PhaseMobilityKernelFactory:: - createAndLaunch< parallelDevicePolicy<> >( m_numPhases, - dataGroup, - fluid, - relperm ); - } - - void ImmiscibleMultiphaseFlow::initializeFluidState( MeshLevel & mesh, - string_array const & regionNames ) - { - GEOS_MARK_FUNCTION; - - mesh.getElemManager().forElementSubRegions( regionNames, - [&]( localIndex const, - ElementSubRegionBase & subRegion ) - { - // 2. Assume global component fractions have been prescribed. - // Initialize constitutive state to get fluid density. - updateFluidModel( subRegion ); - - } ); - - // for some reason CUDA does not want the host_device lambda to be defined inside the generic lambda - // I need the exact type of the subRegion for updateSolidflowProperties to work well. - mesh.getElemManager().forElementSubRegions< CellElementSubRegion, - SurfaceElementSubRegion >( regionNames, [&]( localIndex const, - auto & subRegion ) - { - // 4. Initialize/update dependent state quantities - - // 4.1 Update the constitutive models that only depend on - // - the primary variables - // - the fluid constitutive quantities (as they have already been updated) - // We postpone the other constitutive models for now - // In addition, to avoid multiplying permeability/porosity bay netToGross in the assembly kernel, we do it once and for all here - arrayView1d< real64 const > const netToGross = subRegion.template getField< fields::flow::netToGross >(); - CoupledSolidBase const & porousSolid = - getConstitutiveModel< CoupledSolidBase >( subRegion, subRegion.template getReference< string >( viewKeyStruct::solidNamesString() ) ); - PermeabilityBase const & permeabilityModel = - getConstitutiveModel< PermeabilityBase >( subRegion, subRegion.template getReference< string >( viewKeyStruct::permeabilityNamesString() ) ); - permeabilityModel.scaleHorizontalPermeability( netToGross ); - porousSolid.scaleReferencePorosity( netToGross ); - saveConvergedState( subRegion ); // necessary for a meaningful porosity update in sequential schemes - updatePorosityAndPermeability( subRegion ); - - // Now, we initialize and update each constitutive model one by one - - // 4.2 Save the computed porosity into the old porosity - // - // Note: - // - This must be called after updatePorosityAndPermeability - // - This step depends on porosity - string const & solidName = subRegion.template getReference< string >( viewKeyStruct::solidNamesString() ); - CoupledSolidBase const & porousMaterial = getConstitutiveModel< CoupledSolidBase >( subRegion, solidName ); - porousMaterial.initializeState(); - - // 4.3 Initialize/update the relative permeability model using the initial phase volume fraction - // This is needed to handle relative permeability hysteresis - // Also, initialize the fluid model - // - // Note: - // - This must be called after updateVolumeConstraint - // - This step depends on phaseVolFraction - - // initialized phase volume fraction - arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFrac = - subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); - - string const & relpermName = subRegion.template getReference< string >( viewKeyStruct::relPermNamesString() ); - RelativePermeabilityBase & relPermMaterial = - getConstitutiveModel< RelativePermeabilityBase >( subRegion, relpermName ); - relPermMaterial.saveConvergedPhaseVolFractionState( phaseVolFrac ); // this needs to happen before calling updateRelPermModel - updateRelPermModel( subRegion ); - relPermMaterial.saveConvergedState(); // this needs to happen after calling updateRelPermModel - - // 4.4 Then, we initialize/update the capillary pressure model - // - // Note: - // - This must be called after updatePorosityAndPermeability - // - This step depends on porosity and permeability - if( m_hasCapPressure ) - { - // initialized porosity - arrayView2d< real64 const > const porosity = porousMaterial.getPorosity(); - - string const & permName = subRegion.template getReference< string >( viewKeyStruct::permeabilityNamesString() ); - PermeabilityBase const & permeabilityMaterial = getConstitutiveModel< PermeabilityBase >( subRegion, permName ); - // initialized permeability - arrayView3d< real64 const > const permeability = permeabilityMaterial.permeability(); - - string const & capPressureName = subRegion.template getReference< string >( viewKeyStruct::capPressureNamesString() ); - CapillaryPressureBase const & capPressureMaterial = - getConstitutiveModel< CapillaryPressureBase >( subRegion, capPressureName ); - capPressureMaterial.initializeRockState( porosity, permeability ); // this needs to happen before calling updateCapPressureModel - updateCapPressureModel( subRegion ); - } - - // 4.5 Update the phase mobility - // - // Note: - // - This must be called after updateRelPermModel - // - This step depends phaseRelPerm - updatePhaseMobility( subRegion ); - - } ); - - // 5. Save initial pressure - mesh.getElemManager().forElementSubRegions( regionNames, [&]( localIndex const, - ElementSubRegionBase & subRegion ) - { - arrayView1d< real64 const > const pres = subRegion.getField< fields::flow::pressure >(); - arrayView1d< real64 > const initPres = subRegion.getField< fields::flow::initialPressure >(); - arrayView1d< real64 const > const temp = subRegion.getField< fields::flow::temperature >(); - arrayView1d< real64 > const initTemp = subRegion.template getField< fields::flow::initialTemperature >(); - initPres.setValues< parallelDevicePolicy<> >( pres ); - initTemp.setValues< parallelDevicePolicy<> >( temp ); - - // TODO: Missing updatePhaseMass? - } ); - } - - - void ImmiscibleMultiphaseFlow::initializePostInitialConditionsPreSubGroups() - { - GEOS_MARK_FUNCTION; - - FlowSolverBase::initializePostInitialConditionsPreSubGroups(); - - DomainPartition & domain = this->getGroupByPath< DomainPartition >( "/Problem/domain" ); - - forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, - MeshLevel & mesh, - string_array const & regionNames ) - { - FieldIdentifiers fieldsToBeSync; - fieldsToBeSync.addElementFields( { fields::flow::pressure::key(), - fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key() }, - regionNames ); - - CommunicationTools::getInstance().synchronizeFields( fieldsToBeSync, mesh, domain.getNeighbors(), false ); - } ); - - // Retrieve the numerical methods and finite volume manager - FiniteVolumeManager const & fvManager = domain.getNumericalMethodManager().getFiniteVolumeManager(); - FluxApproximationBase const & fluxApprox = fvManager.getFluxApproximation( m_discretizationName ); - const geos::string flux_approximation_name = fluxApprox.getName(); - - // Clear the existing mapping between connector indices and interface region indices - m_interfaceRegionByConnector.clear(); - forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( std::string const &, - MeshLevel & meshLevel, - string_array const & GEOS_UNUSED_PARAM( regionNames )) - { - // Access the face manager and retrieve the face set group for the current mesh level - FaceManager const & faceManager = meshLevel.getFaceManager(); - Group const & faceSetGroup = faceManager.sets(); - - // Access the connector indices map (face index → connector index) - Group & stencilGroup = - meshLevel.getGroup( FluxApproximationBase::groupKeyStruct::stencilMeshGroupString()) - .getGroup( flux_approximation_name ); - CellElementStencilTPFA & stencil = - stencilGroup.getReference< CellElementStencilTPFA >( - FluxApproximationBase::viewKeyStruct::cellStencilString()); - unordered_map< localIndex, localIndex > const & connectorIndices = stencil.getConnectorIndices(); - - // for all interface face sets to map connector indices to their corresponding interface region indices - for( size_t surfaceRegionIndex = 0; surfaceRegionIndex < m_interfaceFaceSetNames.size(); ++surfaceRegionIndex ) - { - // Iterate over each face and associate its connector index - std::string const & faceSetName = m_interfaceFaceSetNames[surfaceRegionIndex]; - for( localIndex kf : faceSetGroup.getReference< SortedArray< localIndex > >( faceSetName )) - { - auto it = connectorIndices.find( kf ); - if( it != connectorIndices.end()) - { - // Map the connector index to the corresponding surface region index - m_interfaceRegionByConnector[it->second] = surfaceRegionIndex; - } - } - } - } ); - - - initializeState( domain ); - } - - - void - ImmiscibleMultiphaseFlow::implicitStepSetup( real64 const & GEOS_UNUSED_PARAM( time_n ), - real64 const & GEOS_UNUSED_PARAM( dt ), - DomainPartition & domain ) - { - forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, + assembleAccumulationTerm( domain, + dofManager, + localMatrix, + localRhs ); + + + assembleFluxTerms( dt, + domain, + dofManager, + localMatrix, + localRhs ); +} + + + +void ImmiscibleMultiphaseFlow::assembleAccumulationTerm( DomainPartition & domain, + DofManager const & dofManager, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) const +{ + GEOS_MARK_FUNCTION; + + + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, + MeshLevel const & mesh, + string_array const & regionNames ) + { + mesh.getElemManager().forElementSubRegions( regionNames, + [&]( localIndex const, + ElementSubRegionBase const & subRegion ) + { + string const dofKey = dofManager.getKey( viewKeyStruct::elemDofFieldString() ); + string const & solidName = subRegion.getReference< string >( viewKeyStruct::solidNamesString() ); + string const & fluidName = subRegion.getReference< string >( viewKeyStruct::fluidNamesString() ); + + TwoPhaseImmiscibleFluid const & fluid = getConstitutiveModel< TwoPhaseImmiscibleFluid >( subRegion, fluidName ); + CoupledSolidBase const & solid = getConstitutiveModel< CoupledSolidBase >( subRegion, solidName ); + + immiscibleMultiphaseKernels:: + AccumulationKernelFactory:: + createAndLaunch< parallelDevicePolicy<> >( m_numPhases, + dofManager.rankOffset(), + m_useTotalMassEquation, + dofKey, + subRegion, + fluid, + solid, + localMatrix, + localRhs ); + + } ); + } ); +} + +void ImmiscibleMultiphaseFlow::assembleFluxTerms( real64 const dt, + DomainPartition & domain, + DofManager const & dofManager, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) const +{ + GEOS_MARK_FUNCTION; + + NumericalMethodsManager const & numericalMethodManager = domain.getNumericalMethodManager(); + FiniteVolumeManager const & fvManager = numericalMethodManager.getFiniteVolumeManager(); + FluxApproximationBase const & fluxApprox = fvManager.getFluxApproximation( m_discretizationName ); + + string const & dofKey = dofManager.getKey( viewKeyStruct::elemDofFieldString() ); + + + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&] ( string const &, MeshLevel & mesh, string_array const & regionNames ) - { - mesh.getElemManager().forElementSubRegions< CellElementSubRegion, - SurfaceElementSubRegion >( regionNames, - [&]( localIndex const, - auto & subRegion ) - { - saveConvergedState( subRegion ); - - // update porosity, permeability - updatePorosityAndPermeability( subRegion ); - // update all fluid properties - updateVolumeConstraint( subRegion ); - updateFluidState( subRegion ); - - // after the update, save the new saturation - arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFrac = - subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); - - arrayView2d< real64, immiscibleFlow::USD_PHASE > const phaseVolFrac_n = - subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction_n >(); - phaseVolFrac_n.setValues< parallelDevicePolicy<> >( phaseVolFrac ); - - arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const & phaseMass = - subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseMass >(); - - arrayView2d< real64, immiscibleFlow::USD_PHASE > const & phaseMass_n = - subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseMass_n >(); - phaseMass_n.setValues< parallelDevicePolicy<> >( phaseMass ); - - } ); - } ); - } - - void ImmiscibleMultiphaseFlow::assembleSystem( real64 const GEOS_UNUSED_PARAM( time_n ), - real64 const dt, - DomainPartition & domain, - DofManager const & dofManager, - CRSMatrixView< real64, globalIndex const > const & localMatrix, - arrayView1d< real64 > const & localRhs ) - { - GEOS_MARK_FUNCTION; - - assembleAccumulationTerm( domain, - dofManager, - localMatrix, - localRhs ); - - - assembleFluxTerms( dt, - domain, - dofManager, - localMatrix, - localRhs ); - } - - - - void ImmiscibleMultiphaseFlow::assembleAccumulationTerm( DomainPartition & domain, - DofManager const & dofManager, - CRSMatrixView< real64, globalIndex const > const & localMatrix, - arrayView1d< real64 > const & localRhs ) const - { - GEOS_MARK_FUNCTION; - - - forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, - MeshLevel const & mesh, - string_array const & regionNames ) - { - mesh.getElemManager().forElementSubRegions( regionNames, - [&]( localIndex const, - ElementSubRegionBase const & subRegion ) - { - string const dofKey = dofManager.getKey( viewKeyStruct::elemDofFieldString() ); - string const & solidName = subRegion.getReference< string >( viewKeyStruct::solidNamesString() ); - string const & fluidName = subRegion.getReference< string >( viewKeyStruct::fluidNamesString() ); - - TwoPhaseImmiscibleFluid const & fluid = getConstitutiveModel< TwoPhaseImmiscibleFluid >( subRegion, fluidName ); - CoupledSolidBase const & solid = getConstitutiveModel< CoupledSolidBase >( subRegion, solidName ); - - immiscibleMultiphaseKernels:: - AccumulationKernelFactory:: - createAndLaunch< parallelDevicePolicy<> >( m_numPhases, - dofManager.rankOffset(), - m_useTotalMassEquation, - dofKey, - subRegion, - fluid, - solid, - localMatrix, - localRhs ); - - } ); - } ); - } - - void ImmiscibleMultiphaseFlow::assembleFluxTerms( real64 const dt, - DomainPartition & domain, - DofManager const & dofManager, - CRSMatrixView< real64, globalIndex const > const & localMatrix, - arrayView1d< real64 > const & localRhs ) const - { - GEOS_MARK_FUNCTION; - - NumericalMethodsManager const & numericalMethodManager = domain.getNumericalMethodManager(); - FiniteVolumeManager const & fvManager = numericalMethodManager.getFiniteVolumeManager(); - FluxApproximationBase const & fluxApprox = fvManager.getFluxApproximation( m_discretizationName ); - - string const & dofKey = dofManager.getKey( viewKeyStruct::elemDofFieldString() ); - - - forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&] ( string const &, - MeshLevel & mesh, - string_array const & regionNames ) - { - if( m_hasCapPressure ) - { - mesh.getElemManager().forElementSubRegions( regionNames, - [&]( localIndex const, - ElementSubRegionBase & subRegion ) // Check if you need this. - { + { + if( m_hasCapPressure ) + { + mesh.getElemManager().forElementSubRegions( regionNames, + [&]( localIndex const, + ElementSubRegionBase & subRegion ) // Check if you need this. + { // // Capillary pressure wrapper // string const & cappresName = subRegion.getReference< string >( viewKeyStruct::capPressureNamesString() ); // BrooksCoreyCapillaryPressure & capPressure = getConstitutiveModel< BrooksCoreyCapillaryPressure >( subRegion, cappresName ); // CapillaryPressureBase * capPressure1 = &getConstitutiveModel< CapillaryPressureBase >( subRegion, cappresName ); // BrooksCoreyCapillaryPressure::KernelWrapper capPresWrapper = capPressure.createKernelWrapper(); - + // // Relative permeability wrapper // string const & relPermName = subRegion.getReference< string >( viewKeyStruct::relPermNamesString() ); // BrooksCoreyRelativePermeability & relPerm = getConstitutiveModel< BrooksCoreyRelativePermeability >( subRegion, relPermName ); // RelativePermeabilityBase * relPerm1 = &getConstitutiveModel< RelativePermeabilityBase >( subRegion, relPermName ); // BrooksCoreyRelativePermeability::KernelWrapper relPermWrapper = relPerm.createKernelWrapper(); - + // // fluid // string const & fluidName = subRegion.getReference< string >( viewKeyStruct::fluidNamesString() ); // TwoPhaseImmiscibleFluid * fluid = &getConstitutiveModel< TwoPhaseImmiscibleFluid >( subRegion, fluidName ); - + // // m_interfaceConstitutivePairs[0][0] = std::make_tuple( relPerm1, capPressure1, fluid ); // // m_interfaceConstitutivePairs[0][1] = std::make_tuple( relPerm1, capPressure1, fluid ); - + // auto interfaceConstitutivePairs_temp = std::make_tuple( relPerm1, capPressure1, fluid ); - - fluxApprox.forAllStencils( mesh, [&]( auto & stencil ) - { - typename TYPEOFREF( stencil ) ::KernelWrapper stencilWrapper = stencil.createKernelWrapper(); - immiscibleMultiphaseKernels:: - FluxComputeKernelFactory::createAndLaunch< parallelDevicePolicy<> >( m_numPhases, - dofManager.rankOffset(), - dofKey, - m_hasCapPressure, - m_useTotalMassEquation, - m_gravityDensityScheme == GravityDensityScheme::PhasePresence, - getName(), - mesh.getElemManager(), - stencilWrapper, - // capPresWrapper, - // relPermWrapper, - m_interfaceFaceSetNames, - m_interfaceConstitutivePairs, - m_interfaceRegionByConnector, - // interfaceConstitutivePairs_temp, - subRegion, - dt, - localMatrix.toViewConstSizes(), - localRhs.toView() ); - } ); - } ); - } - else - { - fluxApprox.forAllStencils( mesh, [&]( auto & stencil ) - { - typename TYPEOFREF( stencil ) ::KernelWrapper stencilWrapper = stencil.createKernelWrapper(); - immiscibleMultiphaseKernels:: - FluxComputeKernelFactory::createAndLaunch< parallelDevicePolicy<> >( m_numPhases, - dofManager.rankOffset(), - dofKey, - m_hasCapPressure, - m_useTotalMassEquation, - m_gravityDensityScheme == GravityDensityScheme::PhasePresence, - getName(), - mesh.getElemManager(), - stencilWrapper, - dt, - localMatrix.toViewConstSizes(), - localRhs.toView() ); - } ); - } - - } ); - } - - // Ryan: Looks like this will need to be overwritten as well... - // I have left the CompositionalMultiphaseFVM implementation for reference - void ImmiscibleMultiphaseFlow::setupDofs( DomainPartition const & domain, - DofManager & dofManager ) const - { - GEOS_UNUSED_VAR( domain, dofManager ); - // add a field for the cell-centered degrees of freedom - dofManager.addField( viewKeyStruct::elemDofFieldString(), - FieldLocation::Elem, - m_numDofPerCell, - getMeshTargets() ); - - //// this call with instruct GEOS to reorder the dof numbers - //dofManager.setLocalReorderingType( viewKeyStruct::elemDofFieldString(), - // DofManager::LocalReorderingType::ReverseCutHillMcKee ); - - NumericalMethodsManager const & numericalMethodManager = domain.getNumericalMethodManager(); - FiniteVolumeManager const & fvManager = numericalMethodManager.getFiniteVolumeManager(); - FluxApproximationBase const & fluxApprox = fvManager.getFluxApproximation( m_discretizationName ); - dofManager.addCoupling( viewKeyStruct::elemDofFieldString(), fluxApprox ); - } - - void ImmiscibleMultiphaseFlow::applyBoundaryConditions( real64 const time_n, - real64 const dt, - DomainPartition & domain, - DofManager const & dofManager, - CRSMatrixView< real64, globalIndex const > const & localMatrix, - arrayView1d< real64 > const & localRhs ) - { - GEOS_MARK_FUNCTION; - - // apply pressure boundary conditions. - applyDirichletBC( time_n, dt, dofManager, domain, localMatrix.toViewConstSizes(), localRhs.toView() ); - - // apply flux boundary conditions - applySourceFluxBC( time_n, dt, dofManager, domain, localMatrix.toViewConstSizes(), localRhs.toView() ); - } - - - namespace - { - char const bcLogMessage[] = - "ImmiscibleMultiphaseFlow {}: at time {}s, " - "the <{}> boundary condition '{}' is applied to the element set '{}' in subRegion '{}'. " - "\nThe scale of this boundary condition is {} and multiplies the value of the provided function (if any). " - "\nThe total number of target elements (including ghost elements) is {}. " - "\nNote that if this number is equal to zero for all subRegions, the boundary condition will not be applied on this element set."; - } - - bool ImmiscibleMultiphaseFlow::validateDirichletBC( DomainPartition & domain, - real64 const time ) const - { - constexpr integer MAX_NP = 2; - FieldSpecificationManager & fsManager = FieldSpecificationManager::getInstance(); - - bool bcConsistent = true; - - forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, - MeshLevel & mesh, - string_array const & ) - { - // map: regionName -> subRegionName -> setName -> numPhases to check pressure/phase are present consistent - map< string, map< string, map< string, ComponentMask< MAX_NP > > > > bcPresCompStatusMap; - - // 1. Check pressure Dirichlet BCs - fsManager.apply< ElementSubRegionBase >( time, - mesh, - fields::flow::pressure::key(), - [&]( FieldSpecificationBase const &, + + fluxApprox.forAllStencils( mesh, [&]( auto & stencil ) + { + typename TYPEOFREF( stencil ) ::KernelWrapper stencilWrapper = stencil.createKernelWrapper(); + immiscibleMultiphaseKernels:: + FluxComputeKernelFactory::createAndLaunch< parallelDevicePolicy<> >( m_numPhases, + dofManager.rankOffset(), + dofKey, + m_hasCapPressure, + m_useTotalMassEquation, + m_gravityDensityScheme == GravityDensityScheme::PhasePresence, + getName(), + mesh.getElemManager(), + stencilWrapper, + // capPresWrapper, + // relPermWrapper, + m_interfaceFaceSetNames, + m_interfaceConstitutivePairs, + m_interfaceRegionByConnector, + // interfaceConstitutivePairs_temp, + subRegion, + dt, + localMatrix.toViewConstSizes(), + localRhs.toView() ); + } ); + } ); + } + else + { + fluxApprox.forAllStencils( mesh, [&]( auto & stencil ) + { + typename TYPEOFREF( stencil ) ::KernelWrapper stencilWrapper = stencil.createKernelWrapper(); + immiscibleMultiphaseKernels:: + FluxComputeKernelFactory::createAndLaunch< parallelDevicePolicy<> >( m_numPhases, + dofManager.rankOffset(), + dofKey, + m_hasCapPressure, + m_useTotalMassEquation, + m_gravityDensityScheme == GravityDensityScheme::PhasePresence, + getName(), + mesh.getElemManager(), + stencilWrapper, + dt, + localMatrix.toViewConstSizes(), + localRhs.toView() ); + } ); + } + + } ); +} + +// Ryan: Looks like this will need to be overwritten as well... +// I have left the CompositionalMultiphaseFVM implementation for reference +void ImmiscibleMultiphaseFlow::setupDofs( DomainPartition const & domain, + DofManager & dofManager ) const +{ + GEOS_UNUSED_VAR( domain, dofManager ); + // add a field for the cell-centered degrees of freedom + dofManager.addField( viewKeyStruct::elemDofFieldString(), + FieldLocation::Elem, + m_numDofPerCell, + getMeshTargets() ); + + //// this call with instruct GEOS to reorder the dof numbers + //dofManager.setLocalReorderingType( viewKeyStruct::elemDofFieldString(), + // DofManager::LocalReorderingType::ReverseCutHillMcKee ); + + NumericalMethodsManager const & numericalMethodManager = domain.getNumericalMethodManager(); + FiniteVolumeManager const & fvManager = numericalMethodManager.getFiniteVolumeManager(); + FluxApproximationBase const & fluxApprox = fvManager.getFluxApproximation( m_discretizationName ); + dofManager.addCoupling( viewKeyStruct::elemDofFieldString(), fluxApprox ); +} + +void ImmiscibleMultiphaseFlow::applyBoundaryConditions( real64 const time_n, + real64 const dt, + DomainPartition & domain, + DofManager const & dofManager, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) +{ + GEOS_MARK_FUNCTION; + + // apply pressure boundary conditions. + applyDirichletBC( time_n, dt, dofManager, domain, localMatrix.toViewConstSizes(), localRhs.toView() ); + + // apply flux boundary conditions + applySourceFluxBC( time_n, dt, dofManager, domain, localMatrix.toViewConstSizes(), localRhs.toView() ); +} + + +namespace +{ +char const bcLogMessage[] = + "ImmiscibleMultiphaseFlow {}: at time {}s, " + "the <{}> boundary condition '{}' is applied to the element set '{}' in subRegion '{}'. " + "\nThe scale of this boundary condition is {} and multiplies the value of the provided function (if any). " + "\nThe total number of target elements (including ghost elements) is {}. " + "\nNote that if this number is equal to zero for all subRegions, the boundary condition will not be applied on this element set."; +} + +bool ImmiscibleMultiphaseFlow::validateDirichletBC( DomainPartition & domain, + real64 const time ) const +{ + constexpr integer MAX_NP = 2; + FieldSpecificationManager & fsManager = FieldSpecificationManager::getInstance(); + + bool bcConsistent = true; + + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, + MeshLevel & mesh, + string_array const & ) + { + // map: regionName -> subRegionName -> setName -> numPhases to check pressure/phase are present consistent + map< string, map< string, map< string, ComponentMask< MAX_NP > > > > bcPresCompStatusMap; + + // 1. Check pressure Dirichlet BCs + fsManager.apply< ElementSubRegionBase >( time, + mesh, + fields::flow::pressure::key(), + [&]( FieldSpecificationBase const &, + string const & setName, + SortedArrayView< localIndex const > const &, + ElementSubRegionBase & subRegion, + string const & ) + { + // Check whether pressure has already been applied to this set + string const & subRegionName = subRegion.getName(); + string const & regionName = subRegion.getParent().getParent().getName(); + + auto & subRegionSetMap = bcPresCompStatusMap[regionName][subRegionName]; + if( subRegionSetMap.count( setName ) > 0 ) + { + bcConsistent = false; + GEOS_WARNING( BCMessage::pressureConflict( regionName, subRegionName, setName, + fields::flow::pressure::key() ) ); + } + subRegionSetMap[setName].setNumComp( m_numPhases ); + } ); + // 2. Check saturation Dirichlet BCs + fsManager.apply< ElementSubRegionBase >( time, + mesh, + fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key(), + [&] ( FieldSpecificationBase const & fs, string const & setName, SortedArrayView< localIndex const > const &, ElementSubRegionBase & subRegion, string const & ) - { - // Check whether pressure has already been applied to this set - string const & subRegionName = subRegion.getName(); - string const & regionName = subRegion.getParent().getParent().getName(); - - auto & subRegionSetMap = bcPresCompStatusMap[regionName][subRegionName]; - if( subRegionSetMap.count( setName ) > 0 ) - { - bcConsistent = false; - GEOS_WARNING( BCMessage::pressureConflict( regionName, subRegionName, setName, - fields::flow::pressure::key() ) ); - } - subRegionSetMap[setName].setNumComp( m_numPhases ); - } ); - // 2. Check saturation Dirichlet BCs - fsManager.apply< ElementSubRegionBase >( time, - mesh, - fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key(), - [&] ( FieldSpecificationBase const & fs, - string const & setName, - SortedArrayView< localIndex const > const &, - ElementSubRegionBase & subRegion, - string const & ) - { - string const & subRegionName = subRegion.getName( ); - string const & regionName = subRegion.getParent().getParent().getName(); - integer const comp = fs.getComponent(); - - auto & subRegionSetMap = bcPresCompStatusMap[regionName][subRegionName]; - if( subRegionSetMap.count( setName ) == 0 ) - { - bcConsistent = false; - GEOS_WARNING( BCMessage::missingPressure( regionName, subRegionName, setName, - fields::flow::pressure::key() ) ); - } - if( comp < 0 || comp >= m_numPhases ) - { - bcConsistent = false; - GEOS_WARNING( BCMessage::invalidComponentIndex( comp, fs.getName(), - fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key() ) ); - return; // can't check next part with invalid component id - } - - ComponentMask< MAX_NP > & compMask = subRegionSetMap[setName]; - if( compMask[comp] ) - { - bcConsistent = false; - fsManager.forSubGroups< EquilibriumInitialCondition >( [&] ( EquilibriumInitialCondition const & bc ) - { - string_array const & componentNames = bc.getComponentNames(); - GEOS_WARNING( BCMessage::conflictingComposition( comp, componentNames[comp], - regionName, subRegionName, setName, - fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key() ) ); - } ); - } - compMask.set( comp ); - } ); - - // 3.2 Check consistency between composition BC applied to sets - // Note: for a temperature-only boundary condition, this loop does not do anything - for( auto const & regionEntry : bcPresCompStatusMap ) - { - for( auto const & subRegionEntry : regionEntry.second ) - { - for( auto const & setEntry : subRegionEntry.second ) - { - ComponentMask< MAX_NP > const & compMask = setEntry.second; - - fsManager.forSubGroups< EquilibriumInitialCondition >( [&] ( EquilibriumInitialCondition const & fs ) - { - string_array const & componentNames = fs.getComponentNames(); - for( size_t ic = 0; ic < componentNames.size(); ic++ ) - { - if( !compMask[ic] ) - { - bcConsistent = false; - GEOS_WARNING( BCMessage::notAppliedOnRegion( ic, componentNames[ic], - regionEntry.first, subRegionEntry.first, setEntry.first, - fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key() ) ); - } - } - } ); - } - } - } - } ); - - return bcConsistent; - } - - void ImmiscibleMultiphaseFlow::applyDirichletBC( real64 const time_n, + { + string const & subRegionName = subRegion.getName( ); + string const & regionName = subRegion.getParent().getParent().getName(); + integer const comp = fs.getComponent(); + + auto & subRegionSetMap = bcPresCompStatusMap[regionName][subRegionName]; + if( subRegionSetMap.count( setName ) == 0 ) + { + bcConsistent = false; + GEOS_WARNING( BCMessage::missingPressure( regionName, subRegionName, setName, + fields::flow::pressure::key() ) ); + } + if( comp < 0 || comp >= m_numPhases ) + { + bcConsistent = false; + GEOS_WARNING( BCMessage::invalidComponentIndex( comp, fs.getName(), + fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key() ) ); + return; // can't check next part with invalid component id + } + + ComponentMask< MAX_NP > & compMask = subRegionSetMap[setName]; + if( compMask[comp] ) + { + bcConsistent = false; + fsManager.forSubGroups< EquilibriumInitialCondition >( [&] ( EquilibriumInitialCondition const & bc ) + { + string_array const & componentNames = bc.getComponentNames(); + GEOS_WARNING( BCMessage::conflictingComposition( comp, componentNames[comp], + regionName, subRegionName, setName, + fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key() ) ); + } ); + } + compMask.set( comp ); + } ); + + // 3.2 Check consistency between composition BC applied to sets + // Note: for a temperature-only boundary condition, this loop does not do anything + for( auto const & regionEntry : bcPresCompStatusMap ) + { + for( auto const & subRegionEntry : regionEntry.second ) + { + for( auto const & setEntry : subRegionEntry.second ) + { + ComponentMask< MAX_NP > const & compMask = setEntry.second; + + fsManager.forSubGroups< EquilibriumInitialCondition >( [&] ( EquilibriumInitialCondition const & fs ) + { + string_array const & componentNames = fs.getComponentNames(); + for( size_t ic = 0; ic < componentNames.size(); ic++ ) + { + if( !compMask[ic] ) + { + bcConsistent = false; + GEOS_WARNING( BCMessage::notAppliedOnRegion( ic, componentNames[ic], + regionEntry.first, subRegionEntry.first, setEntry.first, + fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key() ) ); + } + } + } ); + } + } + } + } ); + + return bcConsistent; +} + +void ImmiscibleMultiphaseFlow::applyDirichletBC( real64 const time_n, + real64 const dt, + DofManager const & dofManager, + DomainPartition & domain, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) const +{ + GEOS_MARK_FUNCTION; + + // Only validate BC at the beginning of Newton loop + if( m_nonlinearSolverParameters.m_numNewtonIterations == 0 ) + { + bool const bcConsistent = validateDirichletBC( domain, time_n + dt ); + GEOS_ERROR_IF( !bcConsistent, GEOS_FMT( "ImmiscibleMultiphaseFlow {}: inconsistent boundary conditions", getDataContext() ) ); + } + + FieldSpecificationManager & fsManager = FieldSpecificationManager::getInstance(); + + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, + MeshLevel & mesh, + string_array const & ) + { + + // 1. Apply pressure Dirichlet BCs, store in a separate field + applyFieldValue< ElementSubRegionBase >( time_n, dt, mesh, bcLogMessage, + fields::flow::pressure::key(), fields::flow::bcPressure::key() ); + // 2. Apply saturation BC (phase volume fraction) and store in a separate field + applyFieldValue< ElementSubRegionBase >( time_n, dt, mesh, bcLogMessage, + fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key(), + fields::immiscibleMultiphaseFlow::bcPhaseVolumeFraction::key() ); + + globalIndex const rankOffset = dofManager.rankOffset(); + string const dofKey = dofManager.getKey( viewKeyStruct::elemDofFieldString() ); + + // 3. Call constitutive update + fsManager.apply< ElementSubRegionBase >( time_n + dt, + mesh, + fields::flow::pressure::key(), + [&] ( FieldSpecificationBase const &, + string const &, + SortedArrayView< localIndex const > const & targetSet, + ElementSubRegionBase & subRegion, + string const & ) + { + + arrayView1d< real64 const > const bcPres = + subRegion.getReference< array1d< real64 > >( fields::flow::bcPressure::key() ); + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const bcPhaseVolFraction = + subRegion.getReference< array2d< real64, immiscibleFlow::LAYOUT_PHASE > >( + fields::immiscibleMultiphaseFlow::bcPhaseVolumeFraction::key() ); + + arrayView1d< integer const > const ghostRank = + subRegion.getReference< array1d< integer > >( ObjectManagerBase::viewKeyStruct::ghostRankString() ); + arrayView1d< globalIndex const > const dofNumber = + subRegion.getReference< array1d< globalIndex > >( dofKey ); + arrayView1d< real64 const > const pres = + subRegion.getReference< array1d< real64 > >( fields::flow::pressure::key() ); + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFraction = + subRegion.getReference< array2d< real64, immiscibleFlow::LAYOUT_PHASE > >( + fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key() ); + + integer const numPhase = m_numPhases; + + + forAll< parallelDevicePolicy<> >( targetSet.size(), [=] GEOS_HOST_DEVICE ( localIndex const a ) + { + localIndex const ei = targetSet[a]; + if( ghostRank[ei] >= 0 ) + { + return; + } + + globalIndex const dofIndex = dofNumber[ei]; + localIndex const localRow = dofIndex - rankOffset; + real64 rhsValue; + + // 3.1. Apply pressure value to the matrix/rhs + FieldSpecificationEqual::SpecifyFieldValue( dofIndex, + rankOffset, + localMatrix, + rhsValue, + bcPres[ei], + pres[ei] ); + localRhs[localRow] = rhsValue; + + // 3.2. For each phase, apply target saturation value + for( integer ip = 0; ip < numPhase-1; ++ip ) + { + FieldSpecificationEqual::SpecifyFieldValue( dofIndex + ip + 1, + rankOffset, + localMatrix, + rhsValue, + bcPhaseVolFraction[ei][ip], + phaseVolFraction[ei][ip] ); + localRhs[localRow + ip + 1] = rhsValue; + } + } ); + } ); + } ); +} + +void ImmiscibleMultiphaseFlow::applySourceFluxBC( real64 const time, real64 const dt, DofManager const & dofManager, DomainPartition & domain, CRSMatrixView< real64, globalIndex const > const & localMatrix, arrayView1d< real64 > const & localRhs ) const - { - GEOS_MARK_FUNCTION; - - // Only validate BC at the beginning of Newton loop - if( m_nonlinearSolverParameters.m_numNewtonIterations == 0 ) - { - bool const bcConsistent = validateDirichletBC( domain, time_n + dt ); - GEOS_ERROR_IF( !bcConsistent, GEOS_FMT( "ImmiscibleMultiphaseFlow {}: inconsistent boundary conditions", getDataContext() ) ); - } - - FieldSpecificationManager & fsManager = FieldSpecificationManager::getInstance(); - - forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, - MeshLevel & mesh, - string_array const & ) - { - - // 1. Apply pressure Dirichlet BCs, store in a separate field - applyFieldValue< ElementSubRegionBase >( time_n, dt, mesh, bcLogMessage, - fields::flow::pressure::key(), fields::flow::bcPressure::key() ); - // 2. Apply saturation BC (phase volume fraction) and store in a separate field - applyFieldValue< ElementSubRegionBase >( time_n, dt, mesh, bcLogMessage, - fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key(), - fields::immiscibleMultiphaseFlow::bcPhaseVolumeFraction::key() ); - - globalIndex const rankOffset = dofManager.rankOffset(); - string const dofKey = dofManager.getKey( viewKeyStruct::elemDofFieldString() ); - - // 3. Call constitutive update - fsManager.apply< ElementSubRegionBase >( time_n + dt, - mesh, - fields::flow::pressure::key(), - [&] ( FieldSpecificationBase const &, - string const &, - SortedArrayView< localIndex const > const & targetSet, - ElementSubRegionBase & subRegion, - string const & ) - { - - arrayView1d< real64 const > const bcPres = - subRegion.getReference< array1d< real64 > >( fields::flow::bcPressure::key() ); - arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const bcPhaseVolFraction = - subRegion.getReference< array2d< real64, immiscibleFlow::LAYOUT_PHASE > >( - fields::immiscibleMultiphaseFlow::bcPhaseVolumeFraction::key() ); - - arrayView1d< integer const > const ghostRank = - subRegion.getReference< array1d< integer > >( ObjectManagerBase::viewKeyStruct::ghostRankString() ); - arrayView1d< globalIndex const > const dofNumber = - subRegion.getReference< array1d< globalIndex > >( dofKey ); - arrayView1d< real64 const > const pres = - subRegion.getReference< array1d< real64 > >( fields::flow::pressure::key() ); - arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFraction = - subRegion.getReference< array2d< real64, immiscibleFlow::LAYOUT_PHASE > >( - fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key() ); - - integer const numPhase = m_numPhases; - - - forAll< parallelDevicePolicy<> >( targetSet.size(), [=] GEOS_HOST_DEVICE ( localIndex const a ) - { - localIndex const ei = targetSet[a]; - if( ghostRank[ei] >= 0 ) - { - return; - } - - globalIndex const dofIndex = dofNumber[ei]; - localIndex const localRow = dofIndex - rankOffset; - real64 rhsValue; - - // 3.1. Apply pressure value to the matrix/rhs - FieldSpecificationEqual::SpecifyFieldValue( dofIndex, - rankOffset, - localMatrix, - rhsValue, - bcPres[ei], - pres[ei] ); - localRhs[localRow] = rhsValue; - - // 3.2. For each phase, apply target saturation value - for( integer ip = 0; ip < numPhase-1; ++ip ) - { - FieldSpecificationEqual::SpecifyFieldValue( dofIndex + ip + 1, - rankOffset, - localMatrix, - rhsValue, - bcPhaseVolFraction[ei][ip], - phaseVolFraction[ei][ip] ); - localRhs[localRow + ip + 1] = rhsValue; - } - } ); - } ); - } ); - } - - void ImmiscibleMultiphaseFlow::applySourceFluxBC( real64 const time, - real64 const dt, - DofManager const & dofManager, - DomainPartition & domain, - CRSMatrixView< real64, globalIndex const > const & localMatrix, - arrayView1d< real64 > const & localRhs ) const - { - GEOS_MARK_FUNCTION; - - FieldSpecificationManager & fsManager = FieldSpecificationManager::getInstance(); - - string const dofKey = dofManager.getKey( viewKeyStruct::elemDofFieldString() ); - - // Step 1: count individual source flux boundary conditions - - stdMap< string, localIndex > bcNameToBcId; - localIndex bcCounter = 0; - +{ + GEOS_MARK_FUNCTION; + + FieldSpecificationManager & fsManager = FieldSpecificationManager::getInstance(); + + string const dofKey = dofManager.getKey( viewKeyStruct::elemDofFieldString() ); + + // Step 1: count individual source flux boundary conditions + + stdMap< string, localIndex > bcNameToBcId; + localIndex bcCounter = 0; + fsManager.forSubGroups< SourceFluxBoundaryCondition >( [&] ( SourceFluxBoundaryCondition const & bc ) { // collect all the bc names to idx bcNameToBcId.insert( {bc.getName(), bcCounter} ); bcCounter++; } ); - - if( bcCounter == 0 ) - { - return; - } - - // Step 2: count the set size for each source flux (each source flux may have multiple target sets) - - array1d< globalIndex > bcAllSetsSize( bcNameToBcId.size() ); - - computeSourceFluxSizeScalingFactor( time, - dt, - domain, - bcNameToBcId, - bcAllSetsSize.toView() ); - - // Step 3: we are ready to impose the boundary condition, normalized by the set size - - forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, - MeshLevel & mesh, - string_array const & ) - { - - fsManager.apply< ElementSubRegionBase, - SourceFluxBoundaryCondition >( time + dt, - mesh, - SourceFluxBoundaryCondition::catalogName(), - [&]( SourceFluxBoundaryCondition const & fs, - string const & setName, - SortedArrayView< localIndex const > const & targetSet, - ElementSubRegionBase & subRegion, - string const & ) - { - if( fs.getLogLevel() >= 1 && m_nonlinearSolverParameters.m_numNewtonIterations == 0 ) - { - globalIndex const numTargetElems = MpiWrapper::sum< globalIndex >( targetSet.size() ); - GEOS_LOG_RANK_0( GEOS_FMT( bcLogMessage, - getName(), time+dt, fs.getCatalogName(), fs.getName(), - setName, subRegion.getName(), fs.getScale(), numTargetElems ) ); - } - - if( targetSet.size() == 0 ) - { - return; - } - if( !subRegion.hasWrapper( dofKey ) ) - { - if( fs.getLogLevel() >= 1 ) - { - GEOS_LOG_RANK( GEOS_FMT( "{}: trying to apply SourceFlux, but its targetSet named '{}' intersects with non-simulated region named '{}'.", - getDataContext(), setName, subRegion.getName() ) ); - } - return; - } - - arrayView1d< globalIndex const > const dofNumber = subRegion.getReference< array1d< globalIndex > >( dofKey ); - arrayView1d< integer const > const ghostRank = subRegion.ghostRank(); - - // Step 3.1: get the values of the source boundary condition that need to be added to the rhs - - array1d< globalIndex > dofArray( targetSet.size() ); - array1d< real64 > rhsContributionArray( targetSet.size() ); - arrayView1d< real64 > rhsContributionArrayView = rhsContributionArray.toView(); - localIndex const rankOffset = dofManager.rankOffset(); - - RAJA::ReduceSum< parallelDeviceReduce, real64 > massProd( 0.0 ); - - // note that the dofArray will not be used after this step (simpler to use dofNumber instead) - fs.computeRhsContribution< FieldSpecificationAdd, - parallelDevicePolicy<> >( targetSet.toViewConst(), - time + dt, - dt, - subRegion, - dofNumber, - rankOffset, - localMatrix, - dofArray.toView(), - rhsContributionArrayView, - [] GEOS_HOST_DEVICE ( localIndex const ) - { - return 0.0; - } ); - - // Step 3.2: we are ready to add the right-hand side contributions, taking into account our equation layout - - // get the normalizer - real64 const sizeScalingFactor = bcAllSetsSize[bcNameToBcId.at( fs.getName())]; - integer const fluidPhaseId = fs.getComponent(); - integer const numFluidPhases = m_numPhases; - integer useTotalMassEquation = m_useTotalMassEquation; - forAll< parallelDevicePolicy<> >( targetSet.size(), [sizeScalingFactor, - targetSet, - rankOffset, - ghostRank, - fluidPhaseId, - numFluidPhases, - useTotalMassEquation, - dofNumber, - rhsContributionArrayView, - localRhs, - massProd] GEOS_HOST_DEVICE ( localIndex const a ) - { - // we need to filter out ghosts here, because targetSet may contain them - localIndex const ei = targetSet[a]; - if( ghostRank[ei] >= 0 ) - { - return; - } - - real64 const rhsValue = rhsContributionArrayView[a] / sizeScalingFactor; // scale the contribution by the sizeScalingFactor here! - massProd += rhsValue; - if( useTotalMassEquation > 0 ) - { - // for all "fluid components", we add the value to the total mass balance equation - globalIndex const totalMassBalanceRow = dofNumber[ei] - rankOffset; - localRhs[totalMassBalanceRow] += rhsValue; - if( fluidPhaseId < numFluidPhases - 1 ) - { - globalIndex const compMassBalanceRow = totalMassBalanceRow + fluidPhaseId + 1; // component mass bal equations are shifted - localRhs[compMassBalanceRow] += rhsValue; - } - } - else - { - globalIndex const compMassBalanceRow = dofNumber[ei] - rankOffset + fluidPhaseId; - localRhs[compMassBalanceRow] += rhsValue; - } - } ); - - SourceFluxStatsAggregator::forAllFluxStatWrappers( subRegion, fs.getName(), - [&]( SourceFluxStatsAggregator::WrappedStats & wrapper ) - { - // set the new sub-region statistics for this timestep - array1d< real64 > massProdArr{ m_numPhases }; - massProdArr[fluidPhaseId] = massProd.get(); - wrapper.gatherTimeStepStats( time, dt, massProdArr.toViewConst(), targetSet.size() ); - } ); - } ); - } ); - } - - real64 ImmiscibleMultiphaseFlow::calculateResidualNorm( real64 const & GEOS_UNUSED_PARAM( time_n ), - real64 const & GEOS_UNUSED_PARAM( dt ), - DomainPartition const & domain, - DofManager const & dofManager, - arrayView1d< real64 const > const & localRhs ) - { - GEOS_MARK_FUNCTION; - array1d< real64 > localResidualNorm; - array1d< real64 > localResidualNormalizer; - localResidualNorm.resize( numNorm ); - localResidualNormalizer.resize( numNorm ); - - physicsSolverBaseKernels::NormType const normType = getNonlinearSolverParameters().normType(); - - globalIndex const rankOffset = dofManager.rankOffset(); - string const dofKey = dofManager.getKey( viewKeyStruct::elemDofFieldString() ); - - forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, - MeshLevel const & mesh, - string_array const & regionNames ) - { - mesh.getElemManager().forElementSubRegions( regionNames, - [&]( localIndex const, - ElementSubRegionBase const & subRegion ) - { - real64 subRegionResidualNorm[numNorm]{}; - real64 subRegionResidualNormalizer[numNorm]{}; - - string const & solidName = subRegion.getReference< string >( viewKeyStruct::solidNamesString() ); - CoupledSolidBase const & solid = getConstitutiveModel< CoupledSolidBase >( subRegion, solidName ); - - // step 1: compute the norm in the subRegion - - real64 subRegionFlowResidualNorm[1]{}; - real64 subRegionFlowResidualNormalizer[1]{}; - - immiscibleMultiphaseKernels:: - ResidualNormKernelFactory::createAndLaunch< parallelDevicePolicy<> >( normType, - 2, - rankOffset, - dofKey, - localRhs, - subRegion, - solid, - m_nonlinearSolverParameters.m_minNormalizer, - subRegionFlowResidualNorm, - subRegionFlowResidualNormalizer ); - subRegionResidualNorm[0] = subRegionFlowResidualNorm[0]; - subRegionResidualNormalizer[0] = subRegionFlowResidualNormalizer[0]; - - // step 2: first reduction across meshBodies/regions/subRegions - if( normType == physicsSolverBaseKernels::NormType::Linf ) - { - physicsSolverBaseKernels::LinfResidualNormHelper:: - updateLocalNorm< numNorm >( subRegionResidualNorm, localResidualNorm ); - } - else - { - physicsSolverBaseKernels::L2ResidualNormHelper:: - updateLocalNorm< numNorm >( subRegionResidualNorm, subRegionResidualNormalizer, localResidualNorm, localResidualNormalizer ); - } - } ); - } ); - - real64 residualNorm = 0.0; - residualNorm = localResidualNorm[0]; - if( normType == physicsSolverBaseKernels::NormType::Linf ) - { - physicsSolverBaseKernels::LinfResidualNormHelper::computeGlobalNorm( localResidualNorm[0], residualNorm ); - } - else - { - physicsSolverBaseKernels::L2ResidualNormHelper::computeGlobalNorm( localResidualNorm[0], localResidualNormalizer[0], residualNorm ); - } - + + if( bcCounter == 0 ) + { + return; + } + + // Step 2: count the set size for each source flux (each source flux may have multiple target sets) + + array1d< globalIndex > bcAllSetsSize( bcNameToBcId.size() ); + + computeSourceFluxSizeScalingFactor( time, + dt, + domain, + bcNameToBcId, + bcAllSetsSize.toView() ); + + // Step 3: we are ready to impose the boundary condition, normalized by the set size + + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, + MeshLevel & mesh, + string_array const & ) + { + + fsManager.apply< ElementSubRegionBase, + SourceFluxBoundaryCondition >( time + dt, + mesh, + SourceFluxBoundaryCondition::catalogName(), + [&]( SourceFluxBoundaryCondition const & fs, + string const & setName, + SortedArrayView< localIndex const > const & targetSet, + ElementSubRegionBase & subRegion, + string const & ) + { + if( fs.getLogLevel() >= 1 && m_nonlinearSolverParameters.m_numNewtonIterations == 0 ) + { + globalIndex const numTargetElems = MpiWrapper::sum< globalIndex >( targetSet.size() ); + GEOS_LOG_RANK_0( GEOS_FMT( bcLogMessage, + getName(), time+dt, fs.getCatalogName(), fs.getName(), + setName, subRegion.getName(), fs.getScale(), numTargetElems ) ); + } + + if( targetSet.size() == 0 ) + { + return; + } + if( !subRegion.hasWrapper( dofKey ) ) + { + if( fs.getLogLevel() >= 1 ) + { + GEOS_LOG_RANK( GEOS_FMT( "{}: trying to apply SourceFlux, but its targetSet named '{}' intersects with non-simulated region named '{}'.", + getDataContext(), setName, subRegion.getName() ) ); + } + return; + } + + arrayView1d< globalIndex const > const dofNumber = subRegion.getReference< array1d< globalIndex > >( dofKey ); + arrayView1d< integer const > const ghostRank = subRegion.ghostRank(); + + // Step 3.1: get the values of the source boundary condition that need to be added to the rhs + + array1d< globalIndex > dofArray( targetSet.size() ); + array1d< real64 > rhsContributionArray( targetSet.size() ); + arrayView1d< real64 > rhsContributionArrayView = rhsContributionArray.toView(); + localIndex const rankOffset = dofManager.rankOffset(); + + RAJA::ReduceSum< parallelDeviceReduce, real64 > massProd( 0.0 ); + + // note that the dofArray will not be used after this step (simpler to use dofNumber instead) + fs.computeRhsContribution< FieldSpecificationAdd, + parallelDevicePolicy<> >( targetSet.toViewConst(), + time + dt, + dt, + subRegion, + dofNumber, + rankOffset, + localMatrix, + dofArray.toView(), + rhsContributionArrayView, + [] GEOS_HOST_DEVICE ( localIndex const ) + { + return 0.0; + } ); + + // Step 3.2: we are ready to add the right-hand side contributions, taking into account our equation layout + + // get the normalizer + real64 const sizeScalingFactor = bcAllSetsSize[bcNameToBcId.at( fs.getName())]; + integer const fluidPhaseId = fs.getComponent(); + integer const numFluidPhases = m_numPhases; + integer useTotalMassEquation = m_useTotalMassEquation; + forAll< parallelDevicePolicy<> >( targetSet.size(), [sizeScalingFactor, + targetSet, + rankOffset, + ghostRank, + fluidPhaseId, + numFluidPhases, + useTotalMassEquation, + dofNumber, + rhsContributionArrayView, + localRhs, + massProd] GEOS_HOST_DEVICE ( localIndex const a ) + { + // we need to filter out ghosts here, because targetSet may contain them + localIndex const ei = targetSet[a]; + if( ghostRank[ei] >= 0 ) + { + return; + } + + real64 const rhsValue = rhsContributionArrayView[a] / sizeScalingFactor; // scale the contribution by the sizeScalingFactor here! + massProd += rhsValue; + if( useTotalMassEquation > 0 ) + { + // for all "fluid components", we add the value to the total mass balance equation + globalIndex const totalMassBalanceRow = dofNumber[ei] - rankOffset; + localRhs[totalMassBalanceRow] += rhsValue; + if( fluidPhaseId < numFluidPhases - 1 ) + { + globalIndex const compMassBalanceRow = totalMassBalanceRow + fluidPhaseId + 1; // component mass bal equations are shifted + localRhs[compMassBalanceRow] += rhsValue; + } + } + else + { + globalIndex const compMassBalanceRow = dofNumber[ei] - rankOffset + fluidPhaseId; + localRhs[compMassBalanceRow] += rhsValue; + } + } ); + + SourceFluxStatsAggregator::forAllFluxStatWrappers( subRegion, fs.getName(), + [&]( SourceFluxStatsAggregator::WrappedStats & wrapper ) + { + // set the new sub-region statistics for this timestep + array1d< real64 > massProdArr{ m_numPhases }; + massProdArr[fluidPhaseId] = massProd.get(); + wrapper.gatherTimeStepStats( time, dt, massProdArr.toViewConst(), targetSet.size() ); + } ); + } ); + } ); +} + +real64 ImmiscibleMultiphaseFlow::calculateResidualNorm( real64 const & GEOS_UNUSED_PARAM( time_n ), + real64 const & GEOS_UNUSED_PARAM( dt ), + DomainPartition const & domain, + DofManager const & dofManager, + arrayView1d< real64 const > const & localRhs ) +{ + GEOS_MARK_FUNCTION; + array1d< real64 > localResidualNorm; + array1d< real64 > localResidualNormalizer; + localResidualNorm.resize( numNorm ); + localResidualNormalizer.resize( numNorm ); + + physicsSolverBaseKernels::NormType const normType = getNonlinearSolverParameters().normType(); + + globalIndex const rankOffset = dofManager.rankOffset(); + string const dofKey = dofManager.getKey( viewKeyStruct::elemDofFieldString() ); + + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, + MeshLevel const & mesh, + string_array const & regionNames ) + { + mesh.getElemManager().forElementSubRegions( regionNames, + [&]( localIndex const, + ElementSubRegionBase const & subRegion ) + { + real64 subRegionResidualNorm[numNorm]{}; + real64 subRegionResidualNormalizer[numNorm]{}; + + string const & solidName = subRegion.getReference< string >( viewKeyStruct::solidNamesString() ); + CoupledSolidBase const & solid = getConstitutiveModel< CoupledSolidBase >( subRegion, solidName ); + + // step 1: compute the norm in the subRegion + + real64 subRegionFlowResidualNorm[1]{}; + real64 subRegionFlowResidualNormalizer[1]{}; + + immiscibleMultiphaseKernels:: + ResidualNormKernelFactory::createAndLaunch< parallelDevicePolicy<> >( normType, + 2, + rankOffset, + dofKey, + localRhs, + subRegion, + solid, + m_nonlinearSolverParameters.m_minNormalizer, + subRegionFlowResidualNorm, + subRegionFlowResidualNormalizer ); + subRegionResidualNorm[0] = subRegionFlowResidualNorm[0]; + subRegionResidualNormalizer[0] = subRegionFlowResidualNormalizer[0]; + + // step 2: first reduction across meshBodies/regions/subRegions + if( normType == physicsSolverBaseKernels::NormType::Linf ) + { + physicsSolverBaseKernels::LinfResidualNormHelper:: + updateLocalNorm< numNorm >( subRegionResidualNorm, localResidualNorm ); + } + else + { + physicsSolverBaseKernels::L2ResidualNormHelper:: + updateLocalNorm< numNorm >( subRegionResidualNorm, subRegionResidualNormalizer, localResidualNorm, localResidualNormalizer ); + } + } ); + } ); + + real64 residualNorm = 0.0; + residualNorm = localResidualNorm[0]; + if( normType == physicsSolverBaseKernels::NormType::Linf ) + { + physicsSolverBaseKernels::LinfResidualNormHelper::computeGlobalNorm( localResidualNorm[0], residualNorm ); + } + else + { + physicsSolverBaseKernels::L2ResidualNormHelper::computeGlobalNorm( localResidualNorm[0], localResidualNormalizer[0], residualNorm ); + } + GEOS_LOG_LEVEL_RANK_0_NLR( logInfo::ResidualNorm, GEOS_FMT( " ( R{} ) = ( {:4.2e} )", coupledSolverAttributePrefix(), residualNorm )) - - return residualNorm; - } - - void ImmiscibleMultiphaseFlow::applySystemSolution( DofManager const & dofManager, - arrayView1d< real64 const > const & localSolution, - real64 const scalingFactor, - real64 const dt, - DomainPartition & domain ) - { - GEOS_UNUSED_VAR( dt ); - - DofManager::CompMask pressureMask( m_numDofPerCell, 0, 1 ); - - // 1. apply the pressure update - dofManager.addVectorToField( localSolution, - viewKeyStruct::elemDofFieldString(), - fields::flow::pressure::key(), - scalingFactor, - pressureMask ); - - // 2. apply the phaseVolumeFraction update - dofManager.addVectorToField( localSolution, - viewKeyStruct::elemDofFieldString(), - fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key(), - scalingFactor, - ~pressureMask ); - - // 3. synchronize - forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&] ( string const &, - MeshLevel & mesh, - string_array const & regionNames ) - { - std::vector< string > fields{ fields::flow::pressure::key(), fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key() }; - - FieldIdentifiers fieldsToBeSync; - fieldsToBeSync.addElementFields( fields, regionNames ); - - CommunicationTools::getInstance().synchronizeFields( fieldsToBeSync, mesh, domain.getNeighbors(), true ); - } ); - } - - - void ImmiscibleMultiphaseFlow::updateVolumeConstraint( ElementSubRegionBase & subRegion ) const - { - GEOS_MARK_FUNCTION; - - arrayView2d< real64, immiscibleFlow::USD_PHASE > const phaseVolumeFraction = subRegion.getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); - - forAll< parallelDevicePolicy<> >( subRegion.size(), [=] GEOS_HOST_DEVICE ( localIndex const ei ) - { - phaseVolumeFraction[ei][0] = fmin( 1.0, fmax( phaseVolumeFraction[ei][0], 0.0 )); ; - phaseVolumeFraction[ei][1] = 1.0 - phaseVolumeFraction[ei][0]; - } ); - } - - - void ImmiscibleMultiphaseFlow::resetStateToBeginningOfStep( DomainPartition & domain ) - { - GEOS_MARK_FUNCTION; - - forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, - MeshLevel & mesh, - string_array const & regionNames ) - { - mesh.getElemManager().forElementSubRegions< CellElementSubRegion, - SurfaceElementSubRegion >( regionNames, - [&]( localIndex const, - auto & subRegion ) - { - arrayView1d< real64 > const & pres = - subRegion.template getField< fields::flow::pressure >(); - arrayView1d< real64 const > const & pres_n = - subRegion.template getField< fields::flow::pressure_n >(); - pres.setValues< parallelDevicePolicy<> >( pres_n ); - - // after the update, save the new saturation - arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFrac_n = - subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction_n >(); - - arrayView2d< real64, immiscibleFlow::USD_PHASE > const phaseVolFrac = - subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); - phaseVolFrac.setValues< parallelDevicePolicy<> >( phaseVolFrac_n ); - - arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const & phaseMass_n = - subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseMass_n >(); - - arrayView2d< real64, immiscibleFlow::USD_PHASE > const & phaseMass = - subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseMass >(); - phaseMass.setValues< parallelDevicePolicy<> >( phaseMass_n ); - - if( m_isThermal ) - { - arrayView1d< real64 > const & temp = - subRegion.template getField< fields::flow::temperature >(); - arrayView1d< real64 const > const & temp_n = - subRegion.template getField< fields::flow::temperature_n >(); - temp.setValues< parallelDevicePolicy<> >( temp_n ); - } - - // update porosity, permeability - updatePorosityAndPermeability( subRegion ); - // update all fluid properties - updateFluidState( subRegion ); - } ); - } ); - } - - void ImmiscibleMultiphaseFlow::implicitStepComplete( real64 const & time, - real64 const & dt, - DomainPartition & domain ) - { - // Step 1: save the converged aquifer state - // note: we have to save the aquifer state **before** updating the pressure, - // otherwise the aquifer flux is saved with the wrong pressure time level - saveAquiferConvergedState( time, dt, domain ); - - forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, - MeshLevel & mesh, - string_array const & regionNames ) - { - mesh.getElemManager().forElementSubRegions( regionNames, - [&]( localIndex const, - ElementSubRegionBase & subRegion ) - { - // Step 3: save the converged solid state - string const & solidName = subRegion.getReference< string >( viewKeyStruct::solidNamesString() ); - CoupledSolidBase const & porousMaterial = getConstitutiveModel< CoupledSolidBase >( subRegion, solidName ); - if( m_keepVariablesConstantDuringInitStep ) - { - porousMaterial.ignoreConvergedState(); // newPorosity <- porosity_n - } - else - { - porousMaterial.saveConvergedState(); // porosity_n <- porosity - } - - // Step 4: save converged state for the relperm model to handle hysteresis - arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFrac = - subRegion.getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); - string const & relPermName = subRegion.getReference< string >( viewKeyStruct::relPermNamesString() ); - RelativePermeabilityBase const & relPermMaterial = - getConstitutiveModel< RelativePermeabilityBase >( subRegion, relPermName ); - relPermMaterial.saveConvergedPhaseVolFractionState( phaseVolFrac ); - - // Step 5: if capillary pressure is supported, send the converged porosity and permeability to the capillary pressure model - // note: this is needed when the capillary pressure depends on porosity and permeability (Leverett J-function for instance) - if( m_hasCapPressure ) - { - arrayView2d< real64 const > const porosity = porousMaterial.getPorosity(); - - string const & permName = subRegion.getReference< string >( viewKeyStruct::permeabilityNamesString() ); - PermeabilityBase const & permeabilityMaterial = - getConstitutiveModel< PermeabilityBase >( subRegion, permName ); - arrayView3d< real64 const > const permeability = permeabilityMaterial.permeability(); - - string const & capPressName = subRegion.getReference< string >( viewKeyStruct::capPressureNamesString() ); - CapillaryPressureBase const & capPressureMaterial = - getConstitutiveModel< CapillaryPressureBase >( subRegion, capPressName ); - capPressureMaterial.saveConvergedRockState( porosity, permeability ); - } - } ); - } ); - } - - void ImmiscibleMultiphaseFlow::saveConvergedState( ElementSubRegionBase & subRegion ) const - { - FlowSolverBase::saveConvergedState( subRegion ); - - arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFrac = - subRegion.getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); - arrayView2d< real64, immiscibleFlow::USD_PHASE > const phaseVolFrac_n = - subRegion.getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction_n >(); - phaseVolFrac_n.setValues< parallelDevicePolicy<> >( phaseVolFrac ); - - arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseMass = - subRegion.getField< fields::immiscibleMultiphaseFlow::phaseMass >(); - arrayView2d< real64, immiscibleFlow::USD_PHASE > const phaseMass_n = - subRegion.getField< fields::immiscibleMultiphaseFlow::phaseMass_n >(); - phaseMass_n.setValues< parallelDevicePolicy<> >( phaseMass ); - - } - - void ImmiscibleMultiphaseFlow::updateState( DomainPartition & domain ) - { - GEOS_MARK_FUNCTION; - - forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, - MeshLevel & mesh, - string_array const & regionNames ) - { - mesh.getElemManager().forElementSubRegions< CellElementSubRegion, - SurfaceElementSubRegion >( regionNames, [&]( localIndex const, - auto & subRegion ) - { - // update porosity, permeability, and solid internal energy - updatePorosityAndPermeability( subRegion ); - // update all fluid properties - updateVolumeConstraint( subRegion ); - updateFluidState( subRegion ); - } ); - } ); - } - - real64 ImmiscibleMultiphaseFlow::setNextDtBasedOnStateChange( real64 const & currentDt, - DomainPartition & domain ) - { - if( m_targetRelativePresChange >= 1.0 && - m_targetPhaseVolFracChange >= 1.0 ) - { - return LvArray::NumericLimits< real64 >::max; - } - - real64 maxRelativePresChange = 0.0; - real64 maxAbsolutePhaseVolFracChange = 0.0; - - integer const numPhase = m_numPhases; - - forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, + + return residualNorm; +} + +void ImmiscibleMultiphaseFlow::applySystemSolution( DofManager const & dofManager, + arrayView1d< real64 const > const & localSolution, + real64 const scalingFactor, + real64 const dt, + DomainPartition & domain ) +{ + GEOS_UNUSED_VAR( dt ); + + DofManager::CompMask pressureMask( m_numDofPerCell, 0, 1 ); + + // 1. apply the pressure update + dofManager.addVectorToField( localSolution, + viewKeyStruct::elemDofFieldString(), + fields::flow::pressure::key(), + scalingFactor, + pressureMask ); + + // 2. apply the phaseVolumeFraction update + dofManager.addVectorToField( localSolution, + viewKeyStruct::elemDofFieldString(), + fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key(), + scalingFactor, + ~pressureMask ); + + // 3. synchronize + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&] ( string const &, MeshLevel & mesh, string_array const & regionNames ) - { - mesh.getElemManager().forElementSubRegions( regionNames, - [&]( localIndex const, - ElementSubRegionBase & subRegion ) - { - arrayView1d< integer const > const ghostRank = subRegion.ghostRank(); - - arrayView1d< real64 const > const pres = subRegion.getField< fields::flow::pressure >(); - arrayView1d< real64 const > const pres_n = subRegion.getField< fields::flow::pressure_n >(); - arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFrac = - subRegion.getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); - arrayView2d< real64, immiscibleFlow::USD_PHASE > const phaseVolFrac_n = - subRegion.getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction_n >(); - - RAJA::ReduceMax< parallelDeviceReduce, real64 > subRegionMaxPresChange( 0.0 ); - RAJA::ReduceMax< parallelDeviceReduce, real64 > subRegionMaxPhaseVolFracChange( 0.0 ); - - forAll< parallelDevicePolicy<> >( subRegion.size(), [=] GEOS_HOST_DEVICE ( localIndex const ei ) - { - if( ghostRank[ei] < 0 ) - { - // switch from relative to absolute when values less than 1 - subRegionMaxPresChange.max( LvArray::math::abs( pres[ei] - pres_n[ei] ) / LvArray::math::max( LvArray::math::abs( pres_n[ei] ), 1.0 ) ); - for( integer ip = 0; ip < numPhase; ++ip ) - { - subRegionMaxPhaseVolFracChange.max( LvArray::math::abs( phaseVolFrac[ei][ip] - phaseVolFrac_n[ei][ip] ) ); - } - } - } ); - - maxRelativePresChange = LvArray::math::max( maxRelativePresChange, subRegionMaxPresChange.get() ); - maxAbsolutePhaseVolFracChange = LvArray::math::max( maxAbsolutePhaseVolFracChange, subRegionMaxPhaseVolFracChange.get() ); - - } ); - } ); - - maxRelativePresChange = MpiWrapper::max( maxRelativePresChange ); - maxAbsolutePhaseVolFracChange = MpiWrapper::max( maxAbsolutePhaseVolFracChange ); - - GEOS_LOG_LEVEL_RANK_0( logInfo::TimeStep, GEOS_FMT( "{}: max relative pressure change during time step = {} %", - getName(), GEOS_FMT( "{:.{}f}", 100*maxRelativePresChange, 3 ) ) ); - GEOS_LOG_LEVEL_RANK_0( logInfo::TimeStep, GEOS_FMT( "{}: max absolute phase volume fraction change during time step = {}", - getName(), GEOS_FMT( "{:.{}f}", maxAbsolutePhaseVolFracChange, 3 ) ) ); - - real64 const eps = LvArray::NumericLimits< real64 >::epsilon; - - real64 const nextDtPressure = currentDt * ( 1.0 + m_solutionChangeScalingFactor ) * m_targetRelativePresChange - / std::max( eps, maxRelativePresChange + m_solutionChangeScalingFactor * m_targetRelativePresChange ); - if( m_nonlinearSolverParameters.getLogLevel() > 0 ) - GEOS_LOG_RANK_0( GEOS_FMT( "{}: next time step based on pressure change = {}", getName(), nextDtPressure )); - real64 const nextDtPhaseVolFrac = currentDt * ( 1.0 + m_solutionChangeScalingFactor ) * m_targetPhaseVolFracChange - / std::max( eps, maxAbsolutePhaseVolFracChange + m_solutionChangeScalingFactor * m_targetPhaseVolFracChange ); - if( m_nonlinearSolverParameters.getLogLevel() > 0 ) - GEOS_LOG_RANK_0( GEOS_FMT( "{}: next time step based on phase volume fraction change = {}", getName(), nextDtPhaseVolFrac )); - - return std::min( nextDtPressure, nextDtPhaseVolFrac ); - - } - - REGISTER_CATALOG_ENTRY( PhysicsSolverBase, ImmiscibleMultiphaseFlow, string const &, Group * const ) - - } // namespace geos - + { + std::vector< string > fields{ fields::flow::pressure::key(), fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key() }; + + FieldIdentifiers fieldsToBeSync; + fieldsToBeSync.addElementFields( fields, regionNames ); + + CommunicationTools::getInstance().synchronizeFields( fieldsToBeSync, mesh, domain.getNeighbors(), true ); + } ); +} + + +void ImmiscibleMultiphaseFlow::updateVolumeConstraint( ElementSubRegionBase & subRegion ) const +{ + GEOS_MARK_FUNCTION; + + arrayView2d< real64, immiscibleFlow::USD_PHASE > const phaseVolumeFraction = subRegion.getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); + + forAll< parallelDevicePolicy<> >( subRegion.size(), [=] GEOS_HOST_DEVICE ( localIndex const ei ) + { + phaseVolumeFraction[ei][0] = fmin( 1.0, fmax( phaseVolumeFraction[ei][0], 0.0 ));; + phaseVolumeFraction[ei][1] = 1.0 - phaseVolumeFraction[ei][0]; + } ); +} + + +void ImmiscibleMultiphaseFlow::resetStateToBeginningOfStep( DomainPartition & domain ) +{ + GEOS_MARK_FUNCTION; + + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, + MeshLevel & mesh, + string_array const & regionNames ) + { + mesh.getElemManager().forElementSubRegions< CellElementSubRegion, + SurfaceElementSubRegion >( regionNames, + [&]( localIndex const, + auto & subRegion ) + { + arrayView1d< real64 > const & pres = + subRegion.template getField< fields::flow::pressure >(); + arrayView1d< real64 const > const & pres_n = + subRegion.template getField< fields::flow::pressure_n >(); + pres.setValues< parallelDevicePolicy<> >( pres_n ); + + // after the update, save the new saturation + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFrac_n = + subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction_n >(); + + arrayView2d< real64, immiscibleFlow::USD_PHASE > const phaseVolFrac = + subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); + phaseVolFrac.setValues< parallelDevicePolicy<> >( phaseVolFrac_n ); + + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const & phaseMass_n = + subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseMass_n >(); + + arrayView2d< real64, immiscibleFlow::USD_PHASE > const & phaseMass = + subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseMass >(); + phaseMass.setValues< parallelDevicePolicy<> >( phaseMass_n ); + + if( m_isThermal ) + { + arrayView1d< real64 > const & temp = + subRegion.template getField< fields::flow::temperature >(); + arrayView1d< real64 const > const & temp_n = + subRegion.template getField< fields::flow::temperature_n >(); + temp.setValues< parallelDevicePolicy<> >( temp_n ); + } + + // update porosity, permeability + updatePorosityAndPermeability( subRegion ); + // update all fluid properties + updateFluidState( subRegion ); + } ); + } ); +} + +void ImmiscibleMultiphaseFlow::implicitStepComplete( real64 const & time, + real64 const & dt, + DomainPartition & domain ) +{ + // Step 1: save the converged aquifer state + // note: we have to save the aquifer state **before** updating the pressure, + // otherwise the aquifer flux is saved with the wrong pressure time level + saveAquiferConvergedState( time, dt, domain ); + + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, + MeshLevel & mesh, + string_array const & regionNames ) + { + mesh.getElemManager().forElementSubRegions( regionNames, + [&]( localIndex const, + ElementSubRegionBase & subRegion ) + { + // Step 3: save the converged solid state + string const & solidName = subRegion.getReference< string >( viewKeyStruct::solidNamesString() ); + CoupledSolidBase const & porousMaterial = getConstitutiveModel< CoupledSolidBase >( subRegion, solidName ); + if( m_keepVariablesConstantDuringInitStep ) + { + porousMaterial.ignoreConvergedState(); // newPorosity <- porosity_n + } + else + { + porousMaterial.saveConvergedState(); // porosity_n <- porosity + } + + // Step 4: save converged state for the relperm model to handle hysteresis + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFrac = + subRegion.getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); + string const & relPermName = subRegion.getReference< string >( viewKeyStruct::relPermNamesString() ); + RelativePermeabilityBase const & relPermMaterial = + getConstitutiveModel< RelativePermeabilityBase >( subRegion, relPermName ); + relPermMaterial.saveConvergedPhaseVolFractionState( phaseVolFrac ); + + // Step 5: if capillary pressure is supported, send the converged porosity and permeability to the capillary pressure model + // note: this is needed when the capillary pressure depends on porosity and permeability (Leverett J-function for instance) + if( m_hasCapPressure ) + { + arrayView2d< real64 const > const porosity = porousMaterial.getPorosity(); + + string const & permName = subRegion.getReference< string >( viewKeyStruct::permeabilityNamesString() ); + PermeabilityBase const & permeabilityMaterial = + getConstitutiveModel< PermeabilityBase >( subRegion, permName ); + arrayView3d< real64 const > const permeability = permeabilityMaterial.permeability(); + + string const & capPressName = subRegion.getReference< string >( viewKeyStruct::capPressureNamesString() ); + CapillaryPressureBase const & capPressureMaterial = + getConstitutiveModel< CapillaryPressureBase >( subRegion, capPressName ); + capPressureMaterial.saveConvergedRockState( porosity, permeability ); + } + } ); + } ); +} + +void ImmiscibleMultiphaseFlow::saveConvergedState( ElementSubRegionBase & subRegion ) const +{ + FlowSolverBase::saveConvergedState( subRegion ); + + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFrac = + subRegion.getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); + arrayView2d< real64, immiscibleFlow::USD_PHASE > const phaseVolFrac_n = + subRegion.getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction_n >(); + phaseVolFrac_n.setValues< parallelDevicePolicy<> >( phaseVolFrac ); + + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseMass = + subRegion.getField< fields::immiscibleMultiphaseFlow::phaseMass >(); + arrayView2d< real64, immiscibleFlow::USD_PHASE > const phaseMass_n = + subRegion.getField< fields::immiscibleMultiphaseFlow::phaseMass_n >(); + phaseMass_n.setValues< parallelDevicePolicy<> >( phaseMass ); + +} + +void ImmiscibleMultiphaseFlow::updateState( DomainPartition & domain ) +{ + GEOS_MARK_FUNCTION; + + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, + MeshLevel & mesh, + string_array const & regionNames ) + { + mesh.getElemManager().forElementSubRegions< CellElementSubRegion, + SurfaceElementSubRegion >( regionNames, [&]( localIndex const, + auto & subRegion ) + { + // update porosity, permeability, and solid internal energy + updatePorosityAndPermeability( subRegion ); + // update all fluid properties + updateVolumeConstraint( subRegion ); + updateFluidState( subRegion ); + } ); + } ); +} + +real64 ImmiscibleMultiphaseFlow::setNextDtBasedOnStateChange( real64 const & currentDt, + DomainPartition & domain ) +{ + if( m_targetRelativePresChange >= 1.0 && + m_targetPhaseVolFracChange >= 1.0 ) + { + return LvArray::NumericLimits< real64 >::max; + } + + real64 maxRelativePresChange = 0.0; + real64 maxAbsolutePhaseVolFracChange = 0.0; + + integer const numPhase = m_numPhases; + + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, + MeshLevel & mesh, + string_array const & regionNames ) + { + mesh.getElemManager().forElementSubRegions( regionNames, + [&]( localIndex const, + ElementSubRegionBase & subRegion ) + { + arrayView1d< integer const > const ghostRank = subRegion.ghostRank(); + + arrayView1d< real64 const > const pres = subRegion.getField< fields::flow::pressure >(); + arrayView1d< real64 const > const pres_n = subRegion.getField< fields::flow::pressure_n >(); + arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const phaseVolFrac = + subRegion.getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >(); + arrayView2d< real64, immiscibleFlow::USD_PHASE > const phaseVolFrac_n = + subRegion.getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction_n >(); + + RAJA::ReduceMax< parallelDeviceReduce, real64 > subRegionMaxPresChange( 0.0 ); + RAJA::ReduceMax< parallelDeviceReduce, real64 > subRegionMaxPhaseVolFracChange( 0.0 ); + + forAll< parallelDevicePolicy<> >( subRegion.size(), [=] GEOS_HOST_DEVICE ( localIndex const ei ) + { + if( ghostRank[ei] < 0 ) + { + // switch from relative to absolute when values less than 1 + subRegionMaxPresChange.max( LvArray::math::abs( pres[ei] - pres_n[ei] ) / LvArray::math::max( LvArray::math::abs( pres_n[ei] ), 1.0 ) ); + for( integer ip = 0; ip < numPhase; ++ip ) + { + subRegionMaxPhaseVolFracChange.max( LvArray::math::abs( phaseVolFrac[ei][ip] - phaseVolFrac_n[ei][ip] ) ); + } + } + } ); + + maxRelativePresChange = LvArray::math::max( maxRelativePresChange, subRegionMaxPresChange.get() ); + maxAbsolutePhaseVolFracChange = LvArray::math::max( maxAbsolutePhaseVolFracChange, subRegionMaxPhaseVolFracChange.get() ); + + } ); + } ); + + maxRelativePresChange = MpiWrapper::max( maxRelativePresChange ); + maxAbsolutePhaseVolFracChange = MpiWrapper::max( maxAbsolutePhaseVolFracChange ); + + GEOS_LOG_LEVEL_RANK_0( logInfo::TimeStep, GEOS_FMT( "{}: max relative pressure change during time step = {} %", + getName(), GEOS_FMT( "{:.{}f}", 100*maxRelativePresChange, 3 ) ) ); + GEOS_LOG_LEVEL_RANK_0( logInfo::TimeStep, GEOS_FMT( "{}: max absolute phase volume fraction change during time step = {}", + getName(), GEOS_FMT( "{:.{}f}", maxAbsolutePhaseVolFracChange, 3 ) ) ); + + real64 const eps = LvArray::NumericLimits< real64 >::epsilon; + + real64 const nextDtPressure = currentDt * ( 1.0 + m_solutionChangeScalingFactor ) * m_targetRelativePresChange + / std::max( eps, maxRelativePresChange + m_solutionChangeScalingFactor * m_targetRelativePresChange ); + if( m_nonlinearSolverParameters.getLogLevel() > 0 ) + GEOS_LOG_RANK_0( GEOS_FMT( "{}: next time step based on pressure change = {}", getName(), nextDtPressure )); + real64 const nextDtPhaseVolFrac = currentDt * ( 1.0 + m_solutionChangeScalingFactor ) * m_targetPhaseVolFracChange + / std::max( eps, maxAbsolutePhaseVolFracChange + m_solutionChangeScalingFactor * m_targetPhaseVolFracChange ); + if( m_nonlinearSolverParameters.getLogLevel() > 0 ) + GEOS_LOG_RANK_0( GEOS_FMT( "{}: next time step based on phase volume fraction change = {}", getName(), nextDtPhaseVolFrac )); + + return std::min( nextDtPressure, nextDtPhaseVolFrac ); + +} + +REGISTER_CATALOG_ENTRY( PhysicsSolverBase, ImmiscibleMultiphaseFlow, string const &, Group * const ) + +} // namespace geos diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp index f9535bbadba..d1fdeb72625 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp @@ -75,7 +75,7 @@ static void local_solver( real64 uT, stdVector< real64 > saturations, stdVector< stdVector< real64 > trappedSats2, stdVector< real64 > transHat, stdVector< real64 > dTransHat_dP, stdVector< real64 > gravCoefHat, stdVector< real64 > gravCoef, stdVector< real64 > cellCenterDuT, stdVector< real64 > cellCenterDens, stdVector< real64 > cellCenterDens_dP, std::vector< RelativePermeabilityBase * > relPerms, std::vector< CapillaryPressureBase * > capPressures, - std::vector< TwoPhaseImmiscibleFluid * > fluids, std::vector< real64 > &phi, std::vector< real64 > &grad_phi_P, std::vector< real64 > &grad_phi_S, bool &converged ) + std::vector< TwoPhaseImmiscibleFluid * > fluids, std::vector< real64 > & phi, std::vector< real64 > & grad_phi_P, std::vector< real64 > & grad_phi_S, bool & converged ) { // getting wrappers: @@ -204,8 +204,8 @@ static void local_solver( real64 uT, stdVector< real64 > saturations, stdVector< real64 density2[2]{}; real64 dDens_dP2[2][2]{}; - density2[0] = cellCenterDens[0]; - density2[1] = cellCenterDens[1]; + density2[0] = cellCenterDens[0]; + density2[1] = cellCenterDens[1]; dDens_dP2[0][0] = cellCenterDens_dP[0]; dDens_dP2[0][1] = cellCenterDens_dP[1]; @@ -452,18 +452,18 @@ static void local_solver( real64 uT, stdVector< real64 > saturations, stdVector< real64 dhalfFlux_dpc[2][2]{}; //new - real64 fluxVal[2]{}; - real64 dFlux_dP[2][2]{}; - real64 dFlux_dS[2][2]{}; + real64 fluxVal[2]{}; + real64 dFlux_dP[2][2]{}; + real64 dFlux_dS[2][2]{}; - real64 duT_dP[2]{}; - real64 duT_dS[2]{}; + real64 duT_dP[2]{}; + real64 duT_dS[2]{}; - duT_dP[0] = cellCenterDuT[0]; - duT_dP[1] = cellCenterDuT[1]; + duT_dP[0] = cellCenterDuT[0]; + duT_dP[1] = cellCenterDuT[1]; - duT_dS[0] = cellCenterDuT[2]; - duT_dS[1] = cellCenterDuT[3]; + duT_dS[0] = cellCenterDuT[2]; + duT_dS[1] = cellCenterDuT[3]; // initial guess: @@ -488,19 +488,21 @@ static void local_solver( real64 uT, stdVector< real64 > saturations, stdVector< real64 next_Pc_int = 0.0; real64 old_Pc_int = 0.0; real64 old_residual = 0.0; - - if (bisection) { + + if( bisection ) + { Pc_int = fmax( Pc1_max, Pc2_max ); next_Pc_int = fmin( Pc1_min, Pc2_min ); } - if (newton_path){ + if( newton_path ) + { Pc_int = fmax( Pc1_max, Pc2_max ); - Pc_int = 2.0e5; - next_Pc_int = (fmax( Pc1_max, Pc2_max ) - fmin( Pc1_min, Pc2_min )) / (max_iter - 1); - next_Pc_int = (2.0e5 - 5.0e4) / (max_iter - 1); + Pc_int = 2.0e5; + next_Pc_int = (fmax( Pc1_max, Pc2_max ) - fmin( Pc1_min, Pc2_min )) / (max_iter - 1); + next_Pc_int = (2.0e5 - 5.0e4) / (max_iter - 1); } - + real64 Pc_int_iterate = Pc_int; while( iter < max_iter ) @@ -538,9 +540,9 @@ static void local_solver( real64 uT, stdVector< real64 > saturations, stdVector< // truncate the capillary pressure iterate (ensures the inverse will compute a saturation bounded between 0 and 1): Pc_int = fmin( fmax( Pc1_max, Pc2_max ), fmax( Pc_int, fmin( Pc1_min, Pc2_min ) )); - - faceCapPres1[0][0][0] = fmin( Pc1_max, fmax( Pc_int, Pc1_min)); - faceCapPres2[0][0][0] = fmin( Pc2_max, fmax( Pc_int, Pc2_min)); + + faceCapPres1[0][0][0] = fmin( Pc1_max, fmax( Pc_int, Pc1_min )); + faceCapPres2[0][0][0] = fmin( Pc2_max, fmax( Pc_int, Pc2_min )); // Compute the inverse: @@ -565,8 +567,8 @@ static void local_solver( real64 uT, stdVector< real64 > saturations, stdVector< else { capPresWrapper1.computeInv( facePhaseVolFrac1[0], - faceCapPres1[0][0], - dfacePhaseVolFrac_dCapPres1[0][0] ); + faceCapPres1[0][0], + dfacePhaseVolFrac_dCapPres1[0][0] ); facePhaseVolFrac1[0][0] = fmin( 1.0, fmax( facePhaseVolFrac1[0][0], 0.0 )); facePhaseVolFrac1[0][1] = fmin( 1.0, fmax( facePhaseVolFrac1[0][1], 0.0 )); //get derivatives: @@ -597,8 +599,8 @@ static void local_solver( real64 uT, stdVector< real64 > saturations, stdVector< { // evaluating cell-center Pc: capPresWrapper2.computeInv( facePhaseVolFrac2[0], - faceCapPres2[0][0], - dfacePhaseVolFrac_dCapPres2[0][0] ); + faceCapPres2[0][0], + dfacePhaseVolFrac_dCapPres2[0][0] ); facePhaseVolFrac2[0][0] = fmin( 1.0, fmax( facePhaseVolFrac2[0][0], 0.0 )); facePhaseVolFrac2[0][1] = fmin( 1.0, fmax( facePhaseVolFrac2[0][1], 0.0 )); @@ -608,7 +610,7 @@ static void local_solver( real64 uT, stdVector< real64 > saturations, stdVector< faceCapPres2[0][0], dCapPres2_dfacePhaseVolFrac[0][0] ); } - + // compute relative permeability for both faces: using T7 = std::decay_t< decltype(castedRelPerm1) >; @@ -831,9 +833,9 @@ static void local_solver( real64 uT, stdVector< real64 > saturations, stdVector< // *** upwinding *** // compute potential gradient - real64 potGrad = presGrad[ip] - gravHead[ip]; +// real64 potGrad = presGrad[ip] - gravHead[ip]; - potGrad += capGrad[ip]; +// potGrad += capGrad[ip]; // choose upstream cell constexpr int sign[2] = {1, -1}; @@ -948,7 +950,7 @@ static void local_solver( real64 uT, stdVector< real64 > saturations, stdVector< sign[ix] * sign[ip] * mobility[0] * mobility[1] / total_mobility * (dCapGrad_dP[1][ke] - dCapGrad_dP[0][ke]); real64 dC_dS_term1 = sign[ix] * sign[ip] * (dMob_dS[0][ke] * mobility[1] * mobility[1] + dMob_dS[1][ke] * mobility[0] * mobility[0]) / (total_mobility * total_mobility) * - (capGrad[1] -capGrad[0]); + (capGrad[1] -capGrad[0]); real64 dC_dS_term2 = sign[ix] * sign[ip] * (mobility[0] * mobility[1]) / total_mobility; @@ -959,12 +961,15 @@ static void local_solver( real64 uT, stdVector< real64 > saturations, stdVector< dC1_dS[ip][ke] = dC_dS_term1 + dC_dS_term2 * dC_dS_term3; dhalfFlux1_dP[ip][ke] -= dC_dP; dhalfFlux1_dS[ip][ke] -= dC1_dS[ip][ke]; - if (std::fabs(facePhaseVolFrac1[0][0] - 1.0) > 1e-8){ + if( std::fabs( facePhaseVolFrac1[0][0] - 1.0 ) > 1e-8 ) + { dC1_dpc[ip][ke] = dC1_dS[ip][ke] * dfacePhaseVolFrac_dCapPres1[0][0][0][0]; - } else { + } + else + { dC1_dpc[ip][ke] = dC_dS_term1 * dfacePhaseVolFrac_dCapPres1[0][0][0][0]; } - + // GEOS_UNUSED_VAR( dC1_dpc[ip][ke] ); } else @@ -972,9 +977,12 @@ static void local_solver( real64 uT, stdVector< real64 > saturations, stdVector< dC2_dS[ip][ke] = dC_dS_term1 + dC_dS_term2 * dC_dS_term3; dhalfFlux2_dP[ip][ke] -= dC_dP; dhalfFlux2_dS[ip][ke] -= dC2_dS[ip][ke]; - if (std::fabs(facePhaseVolFrac2[0][0] - 1.0) > 1e-8){ + if( std::fabs( facePhaseVolFrac2[0][0] - 1.0 ) > 1e-8 ) + { dC2_dpc[ip][ke] = dC2_dS[ip][ke] * dfacePhaseVolFrac_dCapPres2[0][0][0][0]; - } else { + } + else + { dC2_dpc[ip][ke] = dC_dS_term1 * dfacePhaseVolFrac_dCapPres2[0][0][0][0]; } // GEOS_UNUSED_VAR( dC2_dpc[ip][ke] ); @@ -1040,7 +1048,7 @@ static void local_solver( real64 uT, stdVector< real64 > saturations, stdVector< } else { - if( std::fabs( halfFluxVal[ip][0] ) < 1e-20 ) + if( std::fabs( halfFluxVal[ip][0] ) < 1e-20 ) { k_up_0_check[ip] = k_up_0_b; } @@ -1107,7 +1115,7 @@ static void local_solver( real64 uT, stdVector< real64 > saturations, stdVector< if( std::fabs( local_residual ) < tol ) { // if( std::fabs( dhalfFlux_dpc[0][0] - dhalfFlux_dpc[0][1] ) saturations, stdVector< } else if( div > 1 ) { - local_jacobian = 0.0; - std::cout << "**********************Diverged*******************" << std::endl; - iter = max_iter; + local_jacobian = 0.0; + std::cout << "**********************Diverged*******************" << std::endl; + iter = max_iter; } } else @@ -1141,46 +1149,55 @@ static void local_solver( real64 uT, stdVector< real64 > saturations, stdVector< if( std::fabs( local_residual ) < tol ) { - // if( std::fabs( dhalfFlux_dpc[0][0] - dhalfFlux_dpc[0][1] ) < eps2 ) { - // std::cout << "**********************ZeroJacobian*******************" << std::endl; - // } - converged = 1; + // if( std::fabs( dhalfFlux_dpc[0][0] - dhalfFlux_dpc[0][1] ) < eps2 ) { + // std::cout << "**********************ZeroJacobian*******************" << std::endl; + // } + converged = 1; break; // Converged } // Damping option: - if (damping) { - real64 max_dpc = fmax( fabs(dCapPres1_dfacePhaseVolFrac[0][0][0][0]), fabs(dCapPres2_dfacePhaseVolFrac[0][0][0][0])); - - real64 sign = std::copysign(1.0, deltaPc); - - deltaPc = fmin( fabs(deltaPc), max_dpc * 0.2 ); - deltaPc *= sign; - - } + if( damping ) + { + real64 max_dpc = fmax( fabs( dCapPres1_dfacePhaseVolFrac[0][0][0][0] ), fabs( dCapPres2_dfacePhaseVolFrac[0][0][0][0] )); - if (bisection && iter < 7){ - if ( iter == 0 ){ + real64 sign = std::copysign( 1.0, deltaPc ); + + deltaPc = fmin( fabs( deltaPc ), max_dpc * 0.2 ); + deltaPc *= sign; + + } + + if( bisection && iter < 7 ) + { + if( iter == 0 ) + { old_Pc_int = Pc_int; Pc_int = next_Pc_int; old_residual = local_residual; - } else if (old_residual * local_residual < 0.0 ) { - + } + else if( old_residual * local_residual < 0.0 ) + { + Pc_int = (next_Pc_int + old_Pc_int) / 2.0; old_residual = local_residual; old_Pc_int = next_Pc_int; next_Pc_int = Pc_int; - } else if (old_residual * local_residual > 0.0 ) { - + } + else if( old_residual * local_residual > 0.0 ) + { + Pc_int = old_Pc_int; old_residual = local_residual; old_Pc_int = next_Pc_int; next_Pc_int = Pc_int; - } else { + } + else + { Pc_int = old_Pc_int; old_residual = local_residual; @@ -1189,15 +1206,19 @@ static void local_solver( real64 uT, stdVector< real64 > saturations, stdVector< } - } else if (newton_path){ - Pc_int -= next_Pc_int; + } + else if( newton_path ) + { + Pc_int -= next_Pc_int; + + } + else + { - } else { + Pc_int -= deltaPc; - Pc_int -= deltaPc; + } - } - // truncate the updated capillary pressure (extended capillary pressure condition) for reporting/plotting: @@ -1205,7 +1226,7 @@ static void local_solver( real64 uT, stdVector< real64 > saturations, stdVector< real64 faceCapPres2_plot = fmin( Pc2_max, fmax( Pc_int, Pc2_min )); faceCapPres1_plot = fmin( Pc2_max, fmax( faceCapPres1_plot, Pc2_min )); faceCapPres2_plot = fmin( Pc1_max, fmax( faceCapPres2_plot, Pc1_min )); - + // Write data to the file outFile << GEOS_FMT( "{:10.10e}", local_jacobian ); outFile << GEOS_FMT( ",{:10.10e}", local_residual ); @@ -1238,7 +1259,7 @@ static void local_solver( real64 uT, stdVector< real64 > saturations, stdVector< } - + } // while loop if( converged ) @@ -1266,11 +1287,13 @@ static void local_solver( real64 uT, stdVector< real64 > saturations, stdVector< fluxVal[0] = halfFluxVal[0][0] * density2[0]; fluxVal[1] = halfFluxVal[1][0] * density2[1]; - } else { + } + else + { std::cout << "**********************Diverged*******************" << std::endl; } - + phi[0] = fluxVal[0]; phi[1] = fluxVal[1]; @@ -1342,7 +1365,7 @@ class FluxComputeKernelBase fields::cappres::phaseCapPressure, fields::cappres::dPhaseCapPressure_dPhaseVolFraction >; - // ,fields::cappres::jFuncMultiplier >; + // ,fields::cappres::jFuncMultiplier >; using PermeabilityAccessors = @@ -2085,8 +2108,8 @@ class FluxComputeInterfaceConditionKernel : public FluxComputeKernel< NUM_EQN, N FluxComputeInterfaceConditionKernel( integer const numPhases, globalIndex const rankOffset, STENCILWRAPPER const & stencilWrapper, - // CAPPRESWRAPPER const & capPressureWrapper, - // RELPERMWRAPPER const & relPermWrapper, + // CAPPRESWRAPPER const & capPressureWrapper, + // RELPERMWRAPPER const & relPermWrapper, DofNumberAccessor const & dofNumberAccessor, ImmiscibleMultiphaseFlowAccessors const & multiPhaseFlowAccessors, MultiphaseFluidAccessors const & fluidAccessors, @@ -2103,9 +2126,9 @@ class FluxComputeInterfaceConditionKernel : public FluxComputeKernel< NUM_EQN, N constitutive::CapillaryPressureBase *, constitutive::TwoPhaseImmiscibleFluid * >, 2 > > const & interfaceConstitutivePairs, unordered_map< localIndex, localIndex > const & interfaceRegionByConnector, - // std::tuple< constitutive::RelativePermeabilityBase *, - // constitutive::CapillaryPressureBase *, - // constitutive::TwoPhaseImmiscibleFluid * > const & interfaceConstitutivePairs_temp, + // std::tuple< constitutive::RelativePermeabilityBase *, + // constitutive::CapillaryPressureBase *, + // constitutive::TwoPhaseImmiscibleFluid * > const & interfaceConstitutivePairs_temp, localIndex const GEOS_UNUSED_PARAM( domainSize ) ) : Base( numPhases, rankOffset, @@ -2145,12 +2168,13 @@ class FluxComputeInterfaceConditionKernel : public FluxComputeKernel< NUM_EQN, N FUNC && kernelOp = NoOpFunc{} ) const { - bool connectorHasInterfaceConditionQ = false; - bool anyInterfaceConditionsQ = not m_interfaceConstitutivePairs.empty(); - if (anyInterfaceConditionsQ) { - connectorHasInterfaceConditionQ = - m_interfaceRegionByConnector.find(iconn) != m_interfaceRegionByConnector.end(); - } + bool connectorHasInterfaceConditionQ = false; + bool anyInterfaceConditionsQ = not m_interfaceConstitutivePairs.empty(); + if( anyInterfaceConditionsQ ) + { + connectorHasInterfaceConditionQ = + m_interfaceRegionByConnector.find( iconn ) != m_interfaceRegionByConnector.end(); + } @@ -2470,8 +2494,9 @@ class FluxComputeInterfaceConditionKernel : public FluxComputeKernel< NUM_EQN, N // this determines whether the local solver is needed becuase of heterogeneous capillary pressure regions - // bool notOnInterface = std::fabs( jFMultiplier[0][0] - jFMultiplier[0][1] ) < 1 && std::fabs( jFMultiplier[1][0] - jFMultiplier[1][1] ) < 1; - bool notOnInterface = !connectorHasInterfaceConditionQ; + // bool notOnInterface = std::fabs( jFMultiplier[0][0] - jFMultiplier[0][1] ) < 1 && std::fabs( jFMultiplier[1][0] - + // jFMultiplier[1][1] ) < 1; + bool notOnInterface = !connectorHasInterfaceConditionQ; if( notOnInterface ) { for( integer ip = 0; ip < 2; ++ip ) @@ -2526,47 +2551,50 @@ class FluxComputeInterfaceConditionKernel : public FluxComputeKernel< NUM_EQN, N stdVector< real64 > cellCenterDuTdS = {duT_dP[0], duT_dP[1], duT_dS[0], duT_dS[1]}; stdVector< real64 > cellCenterDens = {density2[0], density2[1]}; stdVector< real64 > cellCenterDens_dP = {dDens_dP2[0][0], dDens_dP2[0][1], dDens_dP2[1][0], dDens_dP2[1][1]}; - // std::vector< RelativePermeabilityBase * > relPerms = {std::get< 0 >( m_interfaceConstitutivePairs_temp ), std::get< 0 >( m_interfaceConstitutivePairs_temp )}; - // std::vector< CapillaryPressureBase * > capPressures = {std::get< 1 >( m_interfaceConstitutivePairs_temp ), std::get< 1 >( m_interfaceConstitutivePairs_temp )}; - // std::vector< TwoPhaseImmiscibleFluid * > fluids = {std::get< 2 >( m_interfaceConstitutivePairs_temp ), std::get< 2 >( m_interfaceConstitutivePairs_temp )}; + // std::vector< RelativePermeabilityBase * > relPerms = {std::get< 0 >( m_interfaceConstitutivePairs_temp ), std::get< 0 >( + // m_interfaceConstitutivePairs_temp )}; + // std::vector< CapillaryPressureBase * > capPressures = {std::get< 1 >( m_interfaceConstitutivePairs_temp ), std::get< 1 >( + // m_interfaceConstitutivePairs_temp )}; + // std::vector< TwoPhaseImmiscibleFluid * > fluids = {std::get< 2 >( m_interfaceConstitutivePairs_temp ), std::get< 2 >( + // m_interfaceConstitutivePairs_temp )}; // auto const & pairArray = m_interfaceConstitutivePairs[0]; - localIndex const surfaceRegionIndex = m_interfaceRegionByConnector.at(iconn); -auto const & pairArray = m_interfaceConstitutivePairs[surfaceRegionIndex]; + localIndex const surfaceRegionIndex = m_interfaceRegionByConnector.at( iconn ); + auto const & pairArray = m_interfaceConstitutivePairs[surfaceRegionIndex]; -std::vector< constitutive::RelativePermeabilityBase * > relPerms = { - std::get<0>( pairArray[0] ), - std::get<0>( pairArray[1] ) -}; + std::vector< constitutive::RelativePermeabilityBase * > relPerms = { + std::get< 0 >( pairArray[0] ), + std::get< 0 >( pairArray[1] ) + }; -std::vector< constitutive::CapillaryPressureBase * > capPressures = { - std::get<1>( pairArray[0] ), - std::get<1>( pairArray[1] ) -}; + std::vector< constitutive::CapillaryPressureBase * > capPressures = { + std::get< 1 >( pairArray[0] ), + std::get< 1 >( pairArray[1] ) + }; -std::vector< constitutive::TwoPhaseImmiscibleFluid * > fluids = { - std::get<2>( pairArray[0] ), - std::get<2>( pairArray[1] ) -}; + std::vector< constitutive::TwoPhaseImmiscibleFluid * > fluids = { + std::get< 2 >( pairArray[0] ), + std::get< 2 >( pairArray[1] ) + }; stdVector< real64 > phi = {halfFluxVal[0][0], halfFluxVal[0][1]}; stdVector< real64 > grad_phi_P = {0.0, 0.0, 0.0, 0.0}; stdVector< real64 > grad_phi_S = {0.0, 0.0, 0.0, 0.0}; - local_solver( uT, saturations, pressures, JFMultipliers, trappedSats1, trappedSats2, transHats, dTransHats_dP, gravCoefHats, gravCoefs, - cellCenterDuTdS, cellCenterDens, cellCenterDens_dP, relPerms, capPressures, fluids, phi, grad_phi_P, grad_phi_S, converged ); - - - fluxVal[0] = phi[0]; - fluxVal[1] = phi[1]; - dFlux_dP[0][0] = grad_phi_P[0]; - dFlux_dP[0][1] = grad_phi_P[1]; - dFlux_dP[1][0] = grad_phi_P[2]; - dFlux_dP[1][1] = grad_phi_P[3]; - dFlux_dS[0][0] = grad_phi_S[0]; - dFlux_dS[0][1] = grad_phi_S[1]; - dFlux_dS[1][0] = grad_phi_S[2]; - dFlux_dS[1][1] = grad_phi_S[3]; + local_solver( uT, saturations, pressures, JFMultipliers, trappedSats1, trappedSats2, transHats, dTransHats_dP, gravCoefHats, gravCoefs, + cellCenterDuTdS, cellCenterDens, cellCenterDens_dP, relPerms, capPressures, fluids, phi, grad_phi_P, grad_phi_S, converged ); + + + fluxVal[0] = phi[0]; + fluxVal[1] = phi[1]; + dFlux_dP[0][0] = grad_phi_P[0]; + dFlux_dP[0][1] = grad_phi_P[1]; + dFlux_dP[1][0] = grad_phi_P[2]; + dFlux_dP[1][1] = grad_phi_P[3]; + dFlux_dS[0][0] = grad_phi_S[0]; + dFlux_dS[0][1] = grad_phi_S[1]; + dFlux_dS[1][0] = grad_phi_S[2]; + dFlux_dS[1][1] = grad_phi_S[3]; // Global residual and jacobian update: for( integer ip = 0; ip < m_numPhases; ++ip ) @@ -2701,16 +2729,16 @@ class FluxComputeKernelFactory string const & solverName, ElementRegionManager const & elemManager, STENCILWRAPPER const & stencilWrapper, - // CAPPRESWRAPPER const & capPresWrapper, - // RELPERMWRAPPER const & relPermWrapper, + // CAPPRESWRAPPER const & capPresWrapper, + // RELPERMWRAPPER const & relPermWrapper, string_array const & interfaceFaceSetNames, stdVector< std::array< std::tuple< constitutive::RelativePermeabilityBase *, constitutive::CapillaryPressureBase *, constitutive::TwoPhaseImmiscibleFluid * >, 2 > > const & interfaceConstitutivePairs, unordered_map< localIndex, localIndex > const & interfaceRegionByConnector, - // std::tuple< constitutive::RelativePermeabilityBase *, - // constitutive::CapillaryPressureBase *, - // constitutive::TwoPhaseImmiscibleFluid * > const & interfaceConstitutivePairs_temp, + // std::tuple< constitutive::RelativePermeabilityBase *, + // constitutive::CapillaryPressureBase *, + // constitutive::TwoPhaseImmiscibleFluid * > const & interfaceConstitutivePairs_temp, ElementSubRegionBase const & subRegion, real64 const & dt, CRSMatrixView< real64, globalIndex const > const & localMatrix, @@ -2724,7 +2752,7 @@ class FluxComputeKernelFactory dofNumberAccessor.setName( solverName + "/accessors/" + dofKey ); // using kernelType = FluxComputeInterfaceConditionKernel< NUM_EQN, NUM_DOF, STENCILWRAPPER, CAPPRESWRAPPER, RELPERMWRAPPER >; - using kernelType = FluxComputeInterfaceConditionKernel< NUM_EQN, NUM_DOF, STENCILWRAPPER >; + using kernelType = FluxComputeInterfaceConditionKernel< NUM_EQN, NUM_DOF, STENCILWRAPPER >; typename kernelType::ImmiscibleMultiphaseFlowAccessors flowAccessors( elemManager, solverName ); typename kernelType::MultiphaseFluidAccessors fluidAccessors( elemManager, solverName ); typename kernelType::CapPressureAccessors capPressureAccessors( elemManager, solverName ); @@ -2733,7 +2761,8 @@ class FluxComputeKernelFactory // kernelType kernel( numPhases, rankOffset, stencilWrapper, capPresWrapper, relPermWrapper, dofNumberAccessor, // flowAccessors, fluidAccessors, capPressureAccessors, permAccessors, // dt, localMatrix, localRhs, hasCapPressure, useTotalMassEquation, - // checkPhasePresenceInGravity, interfaceFaceSetNames, interfaceConstitutivePairs, interfaceRegionByConnector, interfaceConstitutivePairs_temp, domainSize ); + // checkPhasePresenceInGravity, interfaceFaceSetNames, interfaceConstitutivePairs, interfaceRegionByConnector, + // interfaceConstitutivePairs_temp, domainSize ); kernelType kernel( numPhases, rankOffset, stencilWrapper, dofNumberAccessor, flowAccessors, fluidAccessors, capPressureAccessors, permAccessors, dt, localMatrix, localRhs, hasCapPressure, useTotalMassEquation, From 3ec780e381dc9428d9a377c04738987a85d622d6 Mon Sep 17 00:00:00 2001 From: Omar Duran Date: Wed, 4 Feb 2026 22:48:57 -0800 Subject: [PATCH 097/102] Update testImmiscibleInterfaceConditions.cpp --- .../testImmiscibleInterfaceConditions.cpp | 224 +++++++++--------- 1 file changed, 112 insertions(+), 112 deletions(-) diff --git a/src/coreComponents/integrationTests/fluidFlowTests/testImmiscibleInterfaceConditions.cpp b/src/coreComponents/integrationTests/fluidFlowTests/testImmiscibleInterfaceConditions.cpp index be96c05aa4d..e3fd4cdb38e 100644 --- a/src/coreComponents/integrationTests/fluidFlowTests/testImmiscibleInterfaceConditions.cpp +++ b/src/coreComponents/integrationTests/fluidFlowTests/testImmiscibleInterfaceConditions.cpp @@ -47,7 +47,7 @@ CommandLineOptions g_commandLineOptions; TwoPhaseImmiscibleFluid * makeTwoPhaseImmiscibleFluid( TwoPhaseImmiscibleFluid & fluid ) { - + FunctionManager & functionManager = FunctionManager::getInstance(); // 1D table with linear interpolation @@ -56,44 +56,44 @@ TwoPhaseImmiscibleFluid * makeTwoPhaseImmiscibleFluid( TwoPhaseImmiscibleFluid & real64_array densityCoordPhase0; // fill( densityCoordPhase0, Feed< Naxis >{ 0.22, 0.3, 0.5, 0.6, 0.8, 1.0 } ); - for (auto v : {0.0}) - densityCoordPhase0.emplace_back(v); + for( auto v : {0.0} ) + densityCoordPhase0.emplace_back( v ); real64_array densityValuesPhase0; // fill( densityValuesPhase0, Feed< Naxis >{ 0.00603, 0.04224, 0.04224, 0.22423, 0.31311, 0.40203 } ); - for (auto v : {1000.0}) - densityValuesPhase0.emplace_back(v); + for( auto v : {1000.0} ) + densityValuesPhase0.emplace_back( v ); real64_array densityCoordPhase1; // fill( densityCoordPhase1, Feed< Naxis >{ 1.22, 1.3, 1.5, 1.6, 1.8, 2.0 } ); - for (auto v : {0.0}) - densityCoordPhase1.emplace_back(v); + for( auto v : {0.0} ) + densityCoordPhase1.emplace_back( v ); real64_array densityValuesPhase1; // fill( densityValuesPhase1, Feed< Naxis >{ 0.00603, 0.04224, 0.04224, 0.22423, 0.31311, 0.40203 } ); - for (auto v : {100.0}) - densityValuesPhase1.emplace_back(v); + for( auto v : {100.0} ) + densityValuesPhase1.emplace_back( v ); real64_array viscosityCoordPhase0; // fill( viscosityCoordPhase0, Feed< Naxis >{ 0.22, 0.3, 0.5, 0.6, 0.8, 1.0 } ); - for (auto v : {0.0}) - viscosityCoordPhase0.emplace_back(v); + for( auto v : {0.0} ) + viscosityCoordPhase0.emplace_back( v ); real64_array viscosityValuesPhase0; // fill( viscosityValuesPhase0, Feed< Naxis >{ 40203, 31311, 22423, 15011, 4224, 603 } ); - for (auto v : {0.001}) - viscosityValuesPhase0.emplace_back(v); + for( auto v : {0.001} ) + viscosityValuesPhase0.emplace_back( v ); real64_array viscosityCoordPhase1; // fill( viscosityCoordPhase1, Feed< NaxisSingle >{ 0.22 } ); - for (auto v : {0.0}) - viscosityCoordPhase1.emplace_back(v); + for( auto v : {0.0} ) + viscosityCoordPhase1.emplace_back( v ); real64_array viscosityValuesPhase1; // fill( viscosityValuesPhase1, Feed< NaxisSingle >{ 45 } ); - for (auto v : {0.001}) - viscosityValuesPhase1.emplace_back(v); + for( auto v : {0.001} ) + viscosityValuesPhase1.emplace_back( v ); TableFunction & table_density0 = dynamicCast< TableFunction & >( *functionManager.createChild( "TableFunction", "densityTablePhase0" ) ); - array1d coords_density0; - coords_density0.emplace_back(densityCoordPhase0); + array1d< real64_array > coords_density0; + coords_density0.emplace_back( densityCoordPhase0 ); table_density0.setTableCoordinates( coords_density0, { units::Dimensionless } ); table_density0.setTableValues( densityValuesPhase0, units::Dimensionless ); table_density0.reInitializeFunction(); @@ -101,8 +101,8 @@ TwoPhaseImmiscibleFluid * makeTwoPhaseImmiscibleFluid( TwoPhaseImmiscibleFluid & table_density0.setInterpolationMethod( TableFunction::InterpolationType::Linear ); TableFunction & table_density1 = dynamicCast< TableFunction & >( *functionManager.createChild( "TableFunction", "densityTablePhase1" ) ); - array1d coords_density1; - coords_density1.emplace_back(densityCoordPhase1); + array1d< real64_array > coords_density1; + coords_density1.emplace_back( densityCoordPhase1 ); table_density1.setTableCoordinates( coords_density1, { units::Dimensionless } ); table_density1.setTableValues( densityValuesPhase1, units::Dimensionless ); table_density1.reInitializeFunction(); @@ -110,8 +110,8 @@ TwoPhaseImmiscibleFluid * makeTwoPhaseImmiscibleFluid( TwoPhaseImmiscibleFluid & table_density1.setInterpolationMethod( TableFunction::InterpolationType::Linear ); TableFunction & table_viscosity0 = dynamicCast< TableFunction & >( *functionManager.createChild( "TableFunction", "viscosityTablePhase0" ) ); - array1d coords_viscosity0; - coords_viscosity0.emplace_back(viscosityCoordPhase0); + array1d< real64_array > coords_viscosity0; + coords_viscosity0.emplace_back( viscosityCoordPhase0 ); table_viscosity0.setTableCoordinates( coords_viscosity0, { units::Dimensionless } ); table_viscosity0.setTableValues( viscosityValuesPhase0, units::Dimensionless ); table_viscosity0.reInitializeFunction(); @@ -119,8 +119,8 @@ TwoPhaseImmiscibleFluid * makeTwoPhaseImmiscibleFluid( TwoPhaseImmiscibleFluid & table_viscosity0.setInterpolationMethod( TableFunction::InterpolationType::Linear ); TableFunction & table_viscosity1 = dynamicCast< TableFunction & >( *functionManager.createChild( "TableFunction", "viscosityTablePhase1" ) ); - array1d coords_viscosity1; - coords_viscosity1.emplace_back(viscosityCoordPhase1); + array1d< real64_array > coords_viscosity1; + coords_viscosity1.emplace_back( viscosityCoordPhase1 ); table_viscosity1.setTableCoordinates( coords_viscosity1, { units::Dimensionless } ); table_viscosity1.setTableValues( viscosityValuesPhase1, units::Dimensionless ); table_viscosity1.reInitializeFunction(); @@ -482,7 +482,7 @@ class ImmiscibleInterfaceConditionsTest : public FluidModelTest< TwoPhaseImmisci { public: ImmiscibleInterfaceConditionsTest(): state( std::make_unique< CommandLineOptions >( g_commandLineOptions )), - m_parent( "TestParentGroup", m_node ) + m_parent( "TestParentGroup", m_node ) {} @@ -510,9 +510,9 @@ TEST_F( ImmiscibleInterfaceConditionsTest, LocalNonlinearSolverConvergence ) // using Base = FluidModelTest< TwoPhaseImmiscibleFluid, 2 >; createFluid( "fluid", [this]( TwoPhaseImmiscibleFluid & fluid ){ makeTwoPhaseImmiscibleFluid( fluid ); - - // getting constitutive models: - RelativePermeabilityBase & relPerm = makeBrooksCoreyRelPerm( "relPerm" , this->m_parent); + + // getting constitutive models: + RelativePermeabilityBase & relPerm = makeBrooksCoreyRelPerm( "relPerm", this->m_parent ); RelativePermeabilityBase * relPermPtr = &relPerm; // CapillaryPressureBase & capPressure0 = makeJFunctionCapPressureTwoPhase( "capPressure0", this->m_parent ); // CapillaryPressureBase * capPressurePtr0 = &capPressure0; @@ -527,64 +527,64 @@ TEST_F( ImmiscibleInterfaceConditionsTest, LocalNonlinearSolverConvergence ) // CapillaryPressureBase & capPressure1 = makeBrooksCoreyCapPressureTwoPhase2( "capPressure1", this->m_parent ); // CapillaryPressureBase * capPressurePtr1 = &capPressure1; - - std::vector< RelativePermeabilityBase * > relPerms = {relPermPtr, relPermPtr}; - std::vector< CapillaryPressureBase * > capPressures = {capPressurePtr0, capPressurePtr1}; - std::vector< TwoPhaseImmiscibleFluid * > fluids = { &fluid, &fluid }; + + std::vector< RelativePermeabilityBase * > relPerms = {relPermPtr, relPermPtr}; + std::vector< CapillaryPressureBase * > capPressures = {capPressurePtr0, capPressurePtr1}; + std::vector< TwoPhaseImmiscibleFluid * > fluids = { &fluid, &fluid }; // real64 uT = 3.2864545889999906e-05; - - // real64 uT = -3.3e-5; - real64 uT = 1e-17; + + // real64 uT = -3.3e-5; + real64 uT = 1e-17; // real64 uT = 1e-7; - stdVector< real64 > saturations = {0.2, 0.4}; - stdVector< real64 > trappedSats1 = {phase0MinSat1, phase1MinSat1}; - stdVector< real64 > trappedSats2 = {phase0MinSat2, phase1MinSat2}; - stdVector< real64 > pressures = {1e7, 1e7}; - stdVector< real64 > JFMultipliers = {45016.662822296035, 30011.108548197357}; - stdVector< real64 > transHats = {1.9738466000000002e-12, 4.4411548500000007e-12}; - stdVector< real64 > dTransHats_dP = {0.0, 0.0}; - stdVector< real64 > gravCoefHats = {490.5, 490.5}; - stdVector< real64 > gravCoefs = {465.97500000000002, 515.02499999999998}; - - - std::vector< real64 > phi = {0.0, 0.0}; - std::vector< real64 > grad_phi = {0.0, 0.0, 0.0, 0.0}; - - std::ofstream outFile( "local_solver_results.csv" ); - - - // Write data to the file - outFile << "Si"; - outFile << ","; - outFile << "Sj"; - outFile << ","; - outFile << "Fw_alpha"; - outFile << ","; - outFile << "Fn_alpha"; - outFile << ","; - outFile << "Residual_initial"; - outFile << ","; - outFile << "Pc_int"; - outFile << ","; - outFile << "Residual"; - outFile << ","; - outFile << "newton"; - outFile << std::endl; - - real64 const start_sat = 0.0; - real64 const end_sat = 1.0; - real64 const dS = 1e-2; - real64 Si = 0.0; - real64 Sj = 0.9; - - // for( real64 Si = start_sat; Si <= end_sat + 1e-8; Si += dS ) - // { - // for( real64 Sj = start_sat; Sj <= end_sat + 1e-8; Sj += dS ) - // { - saturations[0] = Si; - saturations[1] = Sj; - - auto t0 = std::chrono::high_resolution_clock::now(); + stdVector< real64 > saturations = {0.2, 0.4}; + stdVector< real64 > trappedSats1 = {phase0MinSat1, phase1MinSat1}; + stdVector< real64 > trappedSats2 = {phase0MinSat2, phase1MinSat2}; + stdVector< real64 > pressures = {1e7, 1e7}; + stdVector< real64 > JFMultipliers = {45016.662822296035, 30011.108548197357}; + stdVector< real64 > transHats = {1.9738466000000002e-12, 4.4411548500000007e-12}; + stdVector< real64 > dTransHats_dP = {0.0, 0.0}; + stdVector< real64 > gravCoefHats = {490.5, 490.5}; + stdVector< real64 > gravCoefs = {465.97500000000002, 515.02499999999998}; + + + std::vector< real64 > phi = {0.0, 0.0}; + std::vector< real64 > grad_phi = {0.0, 0.0, 0.0, 0.0}; + + std::ofstream outFile( "local_solver_results.csv" ); + + + // Write data to the file + outFile << "Si"; + outFile << ","; + outFile << "Sj"; + outFile << ","; + outFile << "Fw_alpha"; + outFile << ","; + outFile << "Fn_alpha"; + outFile << ","; + outFile << "Residual_initial"; + outFile << ","; + outFile << "Pc_int"; + outFile << ","; + outFile << "Residual"; + outFile << ","; + outFile << "newton"; + outFile << std::endl; + + real64 const start_sat = 0.0; + real64 const end_sat = 1.0; + real64 const dS = 1e-2; + real64 Si = 0.0; + real64 Sj = 0.9; + + // for( real64 Si = start_sat; Si <= end_sat + 1e-8; Si += dS ) + // { + // for( real64 Sj = start_sat; Sj <= end_sat + 1e-8; Sj += dS ) + // { + saturations[0] = Si; + saturations[1] = Sj; + + auto t0 = std::chrono::high_resolution_clock::now(); // Define missing arguments for the updated signature stdVector< real64 > cellCenterDuT = { 0.0, 0.0 }; @@ -594,39 +594,39 @@ TEST_F( ImmiscibleInterfaceConditionsTest, LocalNonlinearSolverConvergence ) std::vector< real64 > grad_phi_S = { 0.0, 0.0 }; bool converged; -// Call the GEOS local solver + // Call the GEOS local solver geos::immiscibleMultiphaseKernels::local_solver( uT, saturations, pressures, JFMultipliers, trappedSats1, trappedSats2, transHats, dTransHats_dP, gravCoefHats, gravCoefs, - cellCenterDuT, cellCenterDens, cellCenterDens_dP, - relPerms, capPressures, fluids, phi, grad_phi_P, grad_phi_S, converged ); - -auto t1 = std::chrono::high_resolution_clock::now(); -std::chrono::duration elapsed = t1 - t0; -std::cout << "Local solver time: " << elapsed.count() << " s" << std::endl; - - - // Write data to the file - outFile << GEOS_FMT( "{:10.10e}", saturations[0] ); - outFile << GEOS_FMT( ",{:10.10e}", saturations[1] ); - outFile << GEOS_FMT( ",{:10.10e}", phi[0] ); - outFile << GEOS_FMT( ",{:10.10e}", phi[1] ); - outFile << GEOS_FMT( ",{:10.10e}", grad_phi_P[0] ); - outFile << GEOS_FMT( ",{:10.10e}", grad_phi_P[1] ); - outFile << GEOS_FMT( ",{:10.10e}", grad_phi_S[0] ); - outFile << GEOS_FMT( ",{:10.10e}", grad_phi_S[1] ); - outFile << std::endl; - phi[0] = 0; - phi[1] = 0; - grad_phi_P[0] = 0; - grad_phi_P[1] = 0; - grad_phi_S[0] = 0; - grad_phi_S[1] = 0; + cellCenterDuT, cellCenterDens, cellCenterDens_dP, + relPerms, capPressures, fluids, phi, grad_phi_P, grad_phi_S, converged ); + + auto t1 = std::chrono::high_resolution_clock::now(); + std::chrono::duration< double > elapsed = t1 - t0; + std::cout << "Local solver time: " << elapsed.count() << " s" << std::endl; + + + // Write data to the file + outFile << GEOS_FMT( "{:10.10e}", saturations[0] ); + outFile << GEOS_FMT( ",{:10.10e}", saturations[1] ); + outFile << GEOS_FMT( ",{:10.10e}", phi[0] ); + outFile << GEOS_FMT( ",{:10.10e}", phi[1] ); + outFile << GEOS_FMT( ",{:10.10e}", grad_phi_P[0] ); + outFile << GEOS_FMT( ",{:10.10e}", grad_phi_P[1] ); + outFile << GEOS_FMT( ",{:10.10e}", grad_phi_S[0] ); + outFile << GEOS_FMT( ",{:10.10e}", grad_phi_S[1] ); + outFile << std::endl; + phi[0] = 0; + phi[1] = 0; + grad_phi_P[0] = 0; + grad_phi_P[1] = 0; + grad_phi_S[0] = 0; + grad_phi_S[1] = 0; // } // } - outFile.close(); + outFile.close(); -} ); + } ); } int main( int argc, char * *argv ) From 0c2b288791d98e7e81f3c9bfa8874d728483beb8 Mon Sep 17 00:00:00 2001 From: Omar Duran Date: Wed, 4 Feb 2026 23:11:01 -0800 Subject: [PATCH 098/102] Update uni_directional_flow_base.xml --- .../3D_case/uni_directional_flow_base.xml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/uni_directional_flow_base.xml b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/uni_directional_flow_base.xml index eeeefa8277d..79938ce570f 100644 --- a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/uni_directional_flow_base.xml +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/uni_directional_flow_base.xml @@ -10,17 +10,18 @@ discretization="TPFA" temperature="300" initialDt="0.001" - targetRegions="{ region_left, region_right }" - interfaceFaceSetNames = "{ Interface }"> + targetRegions="{ region_left, region_right }"> + - + + From 11bfa6049aa8ac2a344fe5b9e0db7dc6fda1a797 Mon Sep 17 00:00:00 2001 From: Omar Duran Date: Wed, 4 Feb 2026 23:34:22 -0800 Subject: [PATCH 099/102] wip --- .../3D_case/uni_directional_flow_base.xml | 13 +++++++++---- .../uni_directional_flow_interface_condition.xml | 6 +++--- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/uni_directional_flow_base.xml b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/uni_directional_flow_base.xml index 79938ce570f..a07cd1eb482 100644 --- a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/uni_directional_flow_base.xml +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/uni_directional_flow_base.xml @@ -13,15 +13,20 @@ targetRegions="{ region_left, region_right }"> + maxTimeStepCuts="50" + maxSubSteps="100" + lineSearchAction="None" + timeStepDecreaseFactor="0.9" + timeStepIncreaseFactor="1.5" + timeStepDecreaseIterLimit="0.8" + timeStepIncreaseIterLimit="0.6"/> - + diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/uni_directional_flow_interface_condition.xml b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/uni_directional_flow_interface_condition.xml index faea9a0d2e4..3c85d4906ed 100644 --- a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/uni_directional_flow_interface_condition.xml +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/uni_directional_flow_interface_condition.xml @@ -13,9 +13,9 @@ xCoords="{ 0, 10 }" yCoords="{ 0, 6 }" zCoords="{ 0, 5, 10 }" - nx="{ 10 }" - ny="{ 6 }" - nz="{ 10, 10 }" + nx="{ 20 }" + ny="{ 12 }" + nz="{ 20, 20 }" cellBlockNames="{ cb_left, cb_right }"/> From 3d8563943397dd7f8bb71d28fb427e8c3d3bd6e8 Mon Sep 17 00:00:00 2001 From: Omar Duran Date: Wed, 4 Feb 2026 23:54:48 -0800 Subject: [PATCH 100/102] wip: --- .../3D_case/uni_directional_flow_base.xml | 6 +++--- .../3D_case/uni_directional_flow_interface_condition.xml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/uni_directional_flow_base.xml b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/uni_directional_flow_base.xml index a07cd1eb482..17de13549e4 100644 --- a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/uni_directional_flow_base.xml +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/uni_directional_flow_base.xml @@ -6,12 +6,12 @@ gravityVector="{ 0.0, 0.0, 9.81 }"> - + targetRegions="{ region_left, region_right }" + interfaceFaceSetNames = "{ Interface }"> From cbbf98cab9c1378366cc22f50e91944a858d0758 Mon Sep 17 00:00:00 2001 From: Omar Duran Date: Wed, 4 Feb 2026 23:56:21 -0800 Subject: [PATCH 101/102] Update uni_directional_flow_base.xml --- .../3D_case/uni_directional_flow_base.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/uni_directional_flow_base.xml b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/uni_directional_flow_base.xml index 17de13549e4..3982a2b12c6 100644 --- a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/uni_directional_flow_base.xml +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/uni_directional_flow_base.xml @@ -10,8 +10,8 @@ discretization="TPFA" temperature="300" initialDt="0.001" - targetRegions="{ region_left, region_right }" - interfaceFaceSetNames = "{ Interface }"> + targetRegions="{ region_left, region_right }"> + Date: Thu, 5 Feb 2026 00:03:10 -0800 Subject: [PATCH 102/102] Update uni_directional_flow_interface_condition.xml --- .../3D_case/uni_directional_flow_interface_condition.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/uni_directional_flow_interface_condition.xml b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/uni_directional_flow_interface_condition.xml index bac81aa6c20..9bac844ae7b 100644 --- a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/uni_directional_flow_interface_condition.xml +++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/uni_directional_flow_interface_condition.xml @@ -14,7 +14,7 @@ yCoords="{ 0, 6 }" zCoords="{ 0, 5, 10 }" nx="{ 40 }" - ny="{ 24 }" + ny="{ 1 }" nz="{ 40, 40 }" cellBlockNames="{ cb_left, cb_right }"/>