Solid Files¶
Generating solid (.pfsol) files for a ParFlow run can be somewhat of a pain. PFTools has a few features that can help with this process.
Example¶
To see the how Python can help generate solid files, navigate to $PARFLOW_SOURCE/test/python/pfsol/simple-mask/ and open the Python script simple-mask.py. Here, you’ll see the following lines at the top of the script:
from parflow import Run
from parflow.tools.fs import get_absolute_path
from parflow.tools.io import load_patch_matrix_from_sa_file, load_patch_matrix_from_asc_file, load_patch_matrix_from_image_file
from parflow.tools.builders import SolidFileBuilder
By now, you should be familiar with the first two modules and functions. The load_patch_matrix... functions handle different file
types to generate solid files. The SolidFileBuilder class imported from the parflow.tools.builders module handles the matrices of
patches, converting them to ASCII files and passing those to the pfmask-to-pfsol converter in ParFlow. This way, the user doesn’t
have to deal with the more complicated steps.
Lines 52 through 55 show examples of how the patch_matrix functions are used for different types of files:
sabino_mask = load_patch_matrix_from_sa_file(get_absolute_path('Sabino_Mask.sa'))
# sabino_mask = load_patch_matrix_from_asc_file(get_absolute_path('Sabino_Mask.asc'))
# sabino_mask = load_patch_matrix_from_image_file(get_absolute_path('Sabino_Mask.png'))
# sabino_mask = load_patch_matrix_from_image_file(get_absolute_path('Sabino_Mask.tiff'))
Note that only one is used at a time, but all four will work. These functions return a matrix, which is assigned to sabino_mask.
The input files are located in the same directory as the example, so feel free to reference them. Several of these functions have
extra optional arguments, which are described in the full API below.
Next, we’ll show some examples of the SolidFileBuilder class to demonstrate the arguments and methods that can be called on the object:
# Example of using unique ids for each surface [top/bottom/side]
SolidFileBuilder(top=1, bottom=2, side=3) \ # Initializing the SolidFileBuilder
.mask(sabino_mask) \ # Setting the 2D mask
.write('sabino_domain.pfsol', cellsize=90) \ # Write pfsol file
.for_key(sabino.GeomInput.domaininput) # Setting keys to "sabino" Run object that relate to the solid file
# Example using an id mask for the top patches
SolidFileBuilder(bottom=2, side=3) \ # Initializing the SolidFileBuilder
.mask(sabino_mask) \ # Setting the 2D mask
.top_ids(id_array) \ # Using a 2D numpy array to provide patch ids
.write('sabino_domain.pfsol', cellsize=90) # Write pfsol file
# Example using the same matrix to write multiple solid files
SolidFileBuilder(top=1, bottom=2, side=3) \
.mask(sabino_mask) \ # Setting the 2D mask
.write('sabino_domain.pfsol', cellsize=90) \ # Write first pfsol file
.mask(sabino_mask_2) \ # Setting another 2D mask
.side_ids(id_array) \ # Using a 2D numpy array to provide new patch ids (possibly to change boundary conditions)
.write('sabino_domain_2.pfsol', cellsize=90) # Write second pfsol file
Full API: IO tools (from parflow.tools.io)¶
load_patch_matrix_from_pfb_file(file_name, layer=None)- reads in a 2D or 3D ParFlow binary (PFB) filefile_nameand converts it to a patch matrix. If it is a 3D PFB file, the user can specify a vertical layer of the file to convert to the matrix. If no layer is specified, the function will use the top layer of the file.load_patch_matrix_from_image_file(file_name, color_to_patch=None, fall_back_id=0)- reads in an image filefile_nameand converts it to a patch matrix. Thecolor_to_patchargument is a dictionary with hexidecimal colors as keys with their corresponding ID numbers as values. See $PARFLOW_SOURCE/test/python/pfsol/image-as-mask/image-as-mask.py for an example. Ifcolor_to_patchis not provided, it will default to assume that everything in white is not part of the mask and everything else is part of the mask. Thefall_back_idis the ID number for colors that are found in the image but are not specified in thecolor_to_patchdictionary. Its default value is zero.load_patch_matrix_from_asc_file(file_name)- reads in an ASCII filefile_nameand converts it to a patch matrix.load_patch_matrix_from_sa_file(file_name)- reads in a simple ASCII filefile_nameand converts it to a patch matrix.write_patch_matrix_as_asc(matrix, file_name, xllcorner=0.0, yllcorner=0.0, cellsize=1.0, NODATA_value=0)- writes an ASCII file tofile_namefrom the patch matrixmatrix. The argumentsxllcorner,yllcorner,cellsize, andNODATA_valueare necessary for the header of the ASCII file.write_patch_matrix_as_sa(matrix, file_name)- writes a simple ASCII file tofile_namefrom the patch matrixmatrix.
Full API: SolidFileBuilder¶
SolidFileBuilder(top=1, bottom=2, side=3)- initializes a SolidFileBuilder object with default values for the top, bottom, and sides of a domain, respectively.mask(mask_array)- applies the matrix arraymask_arrayto the SolidFileBuilder object.write(self, name, xllcorner=0, yllcorner=0, cellsize=0, vtk=False)- writes theSolidFileBuilderobject data to the .pfsol filename. The argumentsxllcorner,yllcorner, andcellsize=0help define the size of the solid file domain. Ifvtkis set toTrue, it will write a VTK filename.vtkthat you can view in ParaView or another VTK viewer to check that the solid file is correct.for_key(self, geomItem)- sets two keys on theRunobject passed in as thegeomItemargument: 1)geomItem.InputType = 'SolidFile'2)geomItem.FileName = 'name.pfsol'.'name.pfsol'is implicitly referenced from thenameargument of thewritemethod.top(patch_id)- sets the ID number of the top of the solid file domain to the integerpatch_id. This will override thetopargument passed to theSolidFileBuilderobject.bottom(patch_id)- sets the ID number of the bottom of the solid file domain to the integerpatch_id. This will override thebottomargument passed to theSolidFileBuilderobject.side(patch_id)- sets the ID number of the side of the solid file domain to the integerpatch_id. This will override thesideargument passed to theSolidFileBuilderobject.top_ids(top_patch_ids)- sets the ID numbers of the top of the solid file domain to the values in the numpy arraytop_patch_ids.bottom_ids(bottom_patch_ids)- sets the ID numbers of the bottom of the solid file domain to the values in the numpy arraybottom_patch_ids.side_ids(side_patch_ids)- sets the ID numbers of the side of the solid file domain to the values in the numpy arrayside_patch_ids.
More examples¶
Other example scripts showing how to use the SolidFileBuilder can be found in $PARFLOW_SOURCE/test/python/pfsol/. If you have an idea for a new feature or
improvement to the functionality, please let us know, or better yet, become a contributor!