Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Add source value array for fwi in wave solvers #3502

Open
wants to merge 34 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
be056b5
First attempt for fix
acitrain Dec 11, 2024
5346a2d
Bugfix
acitrain Dec 11, 2024
389cb18
Merge branch 'develop' into fix/AddSourceValueTableForFWI
sframba Dec 11, 2024
31de5c1
fix issue calcul cycleNumber
labesse40 Dec 16, 2024
1ba92b0
Merge branch 'develop' into fix/AddSourceValueTableForFWI
acitrain Dec 20, 2024
ddfafef
Merge branch 'develop' into fix/AddSourceValueTableForFWI
acitrain Jan 8, 2025
078e316
uncrustify
acitrain Jan 8, 2025
0988baf
Remove unused variable
acitrain Jan 8, 2025
db08822
Add schema
acitrain Jan 8, 2025
a060ea9
Restore compilation option after push mistake
acitrain Jan 8, 2025
5664509
Merge branch 'develop' into fix/AddSourceValueTableForFWI
acitrain Jan 9, 2025
1386a95
Merge branch 'develop' into fix/AddSourceValueTableForFWI
acitrain Jan 13, 2025
ae06120
Merge branch 'develop' into fix/AddSourceValueTableForFWI
acitrain Jan 14, 2025
dad8001
Merge branch 'develop' into fix/AddSourceValueTableForFWI
acitrain Jan 16, 2025
e341a5e
Merge branch 'develop' into fix/AddSourceValueTableForFWI
acitrain Jan 17, 2025
ac6dc88
Merge branch 'develop' into fix/AddSourceValueTableForFWI
acitrain Jan 22, 2025
b02affd
Fix tolerance on test due to new source
acitrain Jan 22, 2025
8c3f8ae
Merge branch 'develop' into fix/AddSourceValueTableForFWI
acitrain Jan 23, 2025
1b2289e
uncrustify
acitrain Jan 23, 2025
6cfce2e
Merge branch 'develop' into fix/AddSourceValueTableForFWI
acitrain Jan 24, 2025
ac5389d
Merge branch 'develop' into fix/AddSourceValueTableForFWI
acitrain Jan 28, 2025
3fadd88
Fix bug when using cycleNumber
acitrain Jan 28, 2025
cd97257
uncrustify
acitrain Jan 28, 2025
46a0f91
Remove unused variable
acitrain Jan 28, 2025
ff3f6a6
Merge branch 'develop' into fix/AddSourceValueTableForFWI
sframba Jan 29, 2025
10e990b
Add schema files
acitrain Jan 29, 2025
a255893
Merge branch 'develop' into fix/AddSourceValueTableForFWI
acitrain Jan 31, 2025
a124254
Adress some comments
acitrain Jan 31, 2025
45ac53f
Remove unused variable
acitrain Jan 31, 2025
d6486a4
uncrustify
acitrain Feb 3, 2025
ffaa60d
Update integrated hash
acitrain Feb 3, 2025
5b4e015
Add test for table function when we fill sourceValue array
acitrain Feb 4, 2025
bd5bbbb
uncrustify
acitrain Feb 4, 2025
c2cf1d0
Update integrated tests hash
acitrain Feb 4, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .integrated_tests.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
baselines:
bucket: geosx
baseline: integratedTests/baseline_integratedTests-pr3395-9832-31f145e
baseline: integratedTests/baseline_integratedTests-pr3502-10013-5b4e015

allow_fail:
all: ''
streak: ''
6 changes: 5 additions & 1 deletion BASELINE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 #3502 (2025-02-04)
=====================
Add array to store the source values in time inside wave solvers

PR #3395 (2024-01-22)
=====================
Add new fields and change the default input for some tests.
Expand Down Expand Up @@ -128,7 +132,7 @@ Add routine for automatic time steps in waveSolvers with new attributes

PR #3156 (2024-10-29)
====================
Restart check errors due to 1) schema node added to enable thermal option in well model and 2) arrays removed/added for option. Max difference errors due treatment of shutin wells. Previously non-zero rate value reported for shutin well, new code will set rate arrays to zero.
Restart check errors due to 1) schema node added to enable thermal option in well model and 2) arrays removed/added for option. Max difference errors due treatment of shutin wells. Previously non-zero rate value reported for shutin well, new code will set rate arrays to zero.

PR #2878 (2024-10-17)
=====================
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,35 @@ void AcousticWaveEquationSEM::precomputeSourceAndReceiverTerm( MeshLevel & baseM
receiverConstants.setValues< EXEC_POLICY >( -1 );
receiverIsLocal.zero();

arrayView1d< TableFunction::KernelWrapper const > const sourceWaveletTableWrappers = m_sourceWaveletTableWrappers.toViewConst();
bool useSourceWaveletTables = m_useSourceWaveletTables;

//Correct size for sourceValue
EventManager const & event = getGroupByPath< EventManager >( "/Problem/Events" );
real64 const & maxTime = event.getReference< real64 >( EventManager::viewKeyStruct::maxTimeString() );
real64 const & minTime = event.getReference< real64 >( EventManager::viewKeyStruct::minTimeString() );
real64 dt = 0;
for( localIndex numSubEvent = 0; numSubEvent < event.numSubGroups(); ++numSubEvent )
{
EventBase const * subEvent = static_cast< EventBase const * >( event.getSubGroups()[numSubEvent] );
if( subEvent->getEventName() == "/Solvers/" + this->getName() )
{
dt = subEvent->getReference< real64 >( EventBase::viewKeyStruct::forceDtString() );
}
}

real64 dtCompute;

localIndex nSubSteps = (int) ceil( dt/m_timeStep );
dtCompute = dt/nSubSteps;

localIndex const nsamples = int( (maxTime - minTime) / dtCompute) + 1;

localIndex const numSourcesGlobal = m_sourceCoordinates.size( 0 );
m_sourceValue.resize( nsamples, numSourcesGlobal );

arrayView2d< real32 > const sourceValue = m_sourceValue.toView();

mesh.getElemManager().forElementSubRegionsComplete< CellElementSubRegion >( regionNames, [&]( localIndex const,
localIndex const er,
localIndex const esr,
Expand Down Expand Up @@ -192,7 +221,14 @@ void AcousticWaveEquationSEM::precomputeSourceAndReceiverTerm( MeshLevel & baseM
receiverCoordinates,
receiverIsLocal,
receiverNodeIds,
receiverConstants );
receiverConstants,
sourceValue,
dtCompute,
m_timeSourceFrequency,
m_timeSourceDelay,
m_rickerOrder,
sourceWaveletTableWrappers,
useSourceWaveletTables );
}
} );
elementSubRegion.faceList().freeOnDevice();
Expand All @@ -209,25 +245,24 @@ void AcousticWaveEquationSEM::precomputeSourceAndReceiverTerm( MeshLevel & baseM
nodesToElements.freeOnDevice();
}

void AcousticWaveEquationSEM::addSourceToRightHandSide( real64 const & time_n, arrayView1d< real32 > const rhs )
void AcousticWaveEquationSEM::addSourceToRightHandSide( integer const & cycleNumber, arrayView1d< real32 > const rhs )
{
arrayView2d< localIndex const > const sourceNodeIds = m_sourceNodeIds.toViewConst();
arrayView2d< real64 const > const sourceConstants = m_sourceConstants.toViewConst();
arrayView1d< localIndex const > const sourceIsAccessible = m_sourceIsAccessible.toViewConst();
real32 const timeSourceFrequency = m_timeSourceFrequency;
real32 const timeSourceDelay = m_timeSourceDelay;
localIndex const rickerOrder = m_rickerOrder;
bool useSourceWaveletTables = m_useSourceWaveletTables;
arrayView1d< TableFunction::KernelWrapper const > const sourceWaveletTableWrappers = m_sourceWaveletTableWrappers.toViewConst();
arrayView2d< real32 const > const sourceValue = m_sourceValue.toViewConst();

GEOS_THROW_IF( cycleNumber > sourceValue.size( 0 ),
getDataContext() << ": Too many steps compared to array size",
std::runtime_error );
forAll< EXEC_POLICY >( sourceConstants.size( 0 ), [=] GEOS_HOST_DEVICE ( localIndex const isrc )
{
if( sourceIsAccessible[isrc] == 1 )
{
real64 const srcValue =
useSourceWaveletTables ? sourceWaveletTableWrappers[ isrc ].compute( &time_n ) : WaveSolverUtils::evaluateRicker( time_n, timeSourceFrequency, timeSourceDelay, rickerOrder );

for( localIndex inode = 0; inode < sourceConstants.size( 1 ); ++inode )
{
real32 const localIncrement = sourceConstants[isrc][inode] * srcValue;
real32 const localIncrement = sourceConstants[isrc][inode] * sourceValue[cycleNumber][isrc];
RAJA::atomicAdd< ATOMIC_POLICY >( &rhs[sourceNodeIds[isrc][inode]], localIncrement );
}
}
Expand All @@ -252,12 +287,10 @@ void AcousticWaveEquationSEM::initializePostInitialConditionsPreSubGroups()



forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&] ( string const & meshBodyName,
forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&] ( string const &,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&] ( string const &,
forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&] ( string const & meshBodyName,

MeshLevel & mesh,
arrayView1d< string const > const & regionNames )
{
MeshLevel & baseMesh = domain.getMeshBodies().getGroup< MeshBody >( meshBodyName ).getBaseDiscretization();
precomputeSourceAndReceiverTerm( baseMesh, mesh, regionNames );

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
GEOS_UNUSED_VAR( meshBodyName );

NodeManager & nodeManager = mesh.getNodeManager();
FaceManager & faceManager = mesh.getFaceManager();
Expand Down Expand Up @@ -338,6 +371,16 @@ void AcousticWaveEquationSEM::initializePostInitialConditionsPreSubGroups()
m_timeStep=dtOut;
}

forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&] ( string const & meshBodyName,
MeshLevel & mesh,
arrayView1d< string const > const & regionNames )
{
GEOS_UNUSED_VAR( meshBodyName );
MeshLevel & baseMesh = domain.getMeshBodies().getGroup< MeshBody >( meshBodyName ).getBaseDiscretization();
precomputeSourceAndReceiverTerm( baseMesh, mesh, regionNames );

} );


WaveSolverUtils::initTrace( "seismoTraceReceiver", getName(), m_outputSeismoTrace, m_receiverConstants.size( 0 ), m_receiverIsLocal );
}
Expand Down Expand Up @@ -875,7 +918,7 @@ real64 AcousticWaveEquationSEM::explicitStepForward( real64 const & time_n,
DomainPartition & domain,
bool computeGradient )
{
real64 dtCompute = explicitStepInternal( time_n, dt, domain );
real64 dtCompute = explicitStepInternal( time_n, dt, cycleNumber, domain );

forDiscretizationOnMeshTargets( domain.getMeshBodies(),
[&] ( string const &,
Expand Down Expand Up @@ -946,7 +989,7 @@ real64 AcousticWaveEquationSEM::explicitStepBackward( real64 const & time_n,
DomainPartition & domain,
bool computeGradient )
{
real64 dtCompute = explicitStepInternal( time_n, dt, domain );
real64 dtCompute = explicitStepInternal( time_n, dt, cycleNumber, domain );
forDiscretizationOnMeshTargets( domain.getMeshBodies(),
[&] ( string const &,
MeshLevel & mesh,
Expand Down Expand Up @@ -1076,6 +1119,7 @@ void AcousticWaveEquationSEM::prepareNextTimestep( MeshLevel & mesh )

void AcousticWaveEquationSEM::computeUnknowns( real64 const & time_n,
real64 const & dt,
integer const & cycleNumber,
DomainPartition & domain,
MeshLevel & mesh,
arrayView1d< string const > const & regionNames )
Expand Down Expand Up @@ -1103,8 +1147,14 @@ void AcousticWaveEquationSEM::computeUnknowns( real64 const & time_n,
getDiscretizationName(),
"",
kernelFactory );

//Modification of cycleNember useful when minTime < 0
addSourceToRightHandSide( time_n, rhs );
EventManager const & event = getGroupByPath< EventManager >( "/Problem/Events" );
real64 const & minTime = event.getReference< real64 >( EventManager::viewKeyStruct::minTimeString() );
//localIndex const cycleNumber = time_n/dt;
integer const cycleForSource = int(round( -minTime / dt + cycleNumber ));

addSourceToRightHandSide( cycleForSource, rhs );

/// calculate your time integrators
real64 const dt2 = pow( dt, 2 );
Expand Down Expand Up @@ -1228,6 +1278,7 @@ void AcousticWaveEquationSEM::synchronizeUnknowns( real64 const & time_n,

real64 AcousticWaveEquationSEM::explicitStepInternal( real64 const & time_n,
real64 const & dt,
integer const & cycleNumber,
DomainPartition & domain )
{
GEOS_MARK_FUNCTION;
Expand All @@ -1241,7 +1292,7 @@ real64 AcousticWaveEquationSEM::explicitStepInternal( real64 const & time_n,
{
localIndex nSubSteps = (int) ceil( dt/m_timeStep );
dtCompute = dt/nSubSteps;
computeUnknowns( time_n, dtCompute, domain, mesh, regionNames );
computeUnknowns( time_n, dtCompute, cycleNumber, domain, mesh, regionNames );
synchronizeUnknowns( time_n, dtCompute, domain, mesh, regionNames );
} );

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ class AcousticWaveEquationSEM : public WaveSolverBase
* @param cycleNumber the cycle number/step number of evaluation of the source
* @param rhs the right hand side vector to be computed
*/
virtual void addSourceToRightHandSide( real64 const & time_n, arrayView1d< real32 > const rhs );
virtual void addSourceToRightHandSide( integer const & cycleNumber, arrayView1d< real32 > const rhs );


/**
Expand Down Expand Up @@ -123,10 +123,12 @@ class AcousticWaveEquationSEM : public WaveSolverBase
*/
real64 explicitStepInternal( real64 const & time_n,
real64 const & dt,
integer const & cycleNumber,
DomainPartition & domain );

void computeUnknowns( real64 const & time_n,
real64 const & dt,
integer const & cycleNumber,
DomainPartition & domain,
MeshLevel & mesh,
arrayView1d< string const > const & regionNames );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@

real64 AcousticElasticWaveEquationSEM::solverStep( real64 const & time_n,
real64 const & dt,
int const,
integer const cycleNumber,
DomainPartition & domain )
{
GEOS_MARK_FUNCTION;
Expand Down Expand Up @@ -174,7 +174,7 @@

elasSolver->synchronizeUnknowns( time_n, dt, domain, mesh, m_elasRegions );

acousSolver->computeUnknowns( time_n, dt, domain, mesh, m_acousRegions );
acousSolver->computeUnknowns( time_n, dt, cycleNumber, domain, mesh, m_acousRegions );

Check warning on line 177 in src/coreComponents/physicsSolvers/wavePropagation/sem/acoustoelastic/secondOrderEqn/isotropic/AcousticElasticWaveEquationSEM.cpp

View check run for this annotation

Codecov / codecov/patch

src/coreComponents/physicsSolvers/wavePropagation/sem/acoustoelastic/secondOrderEqn/isotropic/AcousticElasticWaveEquationSEM.cpp#L177

Added line #L177 was not covered by tests

forAll< EXEC_POLICY >( interfaceNodesSet.size(), [=] GEOS_HOST_DEVICE ( localIndex const in )
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,14 @@
arrayView2d< real64 const > const receiverCoordinates,
arrayView1d< localIndex > const receiverIsLocal,
arrayView2d< localIndex > const receiverNodeIds,
arrayView2d< real64 > const receiverConstants )
arrayView2d< real64 > const receiverConstants,
arrayView2d< real32 > const sourceValue,
real64 const dt,
real32 const timeSourceFrequency,
real32 const timeSourceDelay,
localIndex const rickerOrder,
arrayView1d< TableFunction::KernelWrapper const > const sourceWaveletTableWrappers,
bool useSourceWaveletTables )
{
constexpr localIndex numNodesPerElem = FE_TYPE::numNodes;

Expand Down Expand Up @@ -121,6 +128,20 @@
sourceNodeIds[isrc][a] = elemsToNodes( k, a );
sourceConstants[isrc][a] = Ntest[a];
}

for( localIndex cycle = 0; cycle < sourceValue.size( 0 ); ++cycle )
{
real64 const time_n = cycle * dt;
if( useSourceWaveletTables )
{
sourceValue[cycle][isrc]= sourceWaveletTableWrappers[ isrc ].compute( &time_n );

Check warning on line 137 in src/coreComponents/physicsSolvers/wavePropagation/shared/PrecomputeSourcesAndReceiversKernel.hpp

View check run for this annotation

Codecov / codecov/patch

src/coreComponents/physicsSolvers/wavePropagation/shared/PrecomputeSourcesAndReceiversKernel.hpp#L137

Added line #L137 was not covered by tests
}
else
{
sourceValue[cycle][isrc] = WaveSolverUtils::evaluateRicker( cycle * dt, timeSourceFrequency, timeSourceDelay, rickerOrder );
}
}

}
}
} // end loop over all sources
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,13 @@ WaveSolverBase::WaveSolverBase( const std::string & name,
setSizedFromParent( 0 ).
setDescription( "Coordinates (x,y,z) of the receivers" );

registerWrapper( viewKeyStruct::sourceValueString(), &m_sourceValue ).
setInputFlag( InputFlags::FALSE ).
setRestartFlags( RestartFlags::NO_WRITE ).
setSizedFromParent( 0 ).
setDescription( "Array which contains the value of the Ricker wavelets at each time-steps" );


registerWrapper( viewKeyStruct::timeSourceDelayString(), &m_timeSourceDelay ).
setInputFlag( InputFlags::OPTIONAL ).
setApplyDefaultValue( -1 ).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ class WaveSolverBase : public PhysicsSolverBase
struct viewKeyStruct : PhysicsSolverBase::viewKeyStruct
{
static constexpr char const * sourceCoordinatesString() { return "sourceCoordinates"; }
static constexpr char const * sourceValueString() { return "sourceValue"; }

static constexpr char const * timeSourceFrequencyString() { return "timeSourceFrequency"; }
static constexpr char const * timeSourceDelayString() { return "timeSourceDelay"; }
Expand Down Expand Up @@ -254,6 +255,9 @@ class WaveSolverBase : public PhysicsSolverBase

localIndex getNumNodesPerElem();

/// Precomputed value of the source terms
array2d< real32 > m_sourceValue;

/// Coordinates of the sources in the mesh
array2d< real64 > m_sourceCoordinates;

Expand Down
Loading