Afternoon,
I have a csv file with:
- boreholes (1, 2, 3,..., b) characteristics ('x', head, 1st layer top level, 1st layer bottom level, 2nd layer bottom level, 3rd layer bottom level, ..., lth layer bottom level);
- material (1, 2, 3, ..., m) characteristics (to be assigned to each soil layer that each borehole).
Whilst I managed to get the Python script reading the csv files, trying to set boreholes/layers/materials in loops has been more complex (I would like the script to be run for as many boreholes/layer/materials as needed). All examples I have seen, so far, are for basic ground models with horizontal layers defined by a single borehole. Is there a way to set as many boreholes as needed, change the top and bottom layers levels, head, ‘x’ coordination in a loop?
From what I have seen g_i.borehole(x) creates Borehole_1, and if I repeat g_i.borehole(x) Borehole_2 is created, and so on. How can I access and change the characteristics of each borehole, using a Python script, for any number of boreholes >1?
How can layers characteristics be set for each borehole, and a material set for each of those layer, in a loop?
Apologies if this question has been asked before but, I couldn’t find it in the forum.
Cheers,
Joao
Dear Joao Ferreira Verde
Can you share your csv files with us?
Dear Micha,
I have uploaded the csv file to this response.
1) The csv file providing the information of several boreholes which I wanted to use initially - layers levels are indicated as top level for the first layer, and then bottom level for the other deeper soil layers. I was unable to set the levels inside the boreholes in a loop that could read the information from the csv. My goal is to be able to access the borehole using a loop and changing the layers level using a loop as well.
2) I guess that I am experiencing a similar problem by looping through polygons that meet a certain criteria, whilst trying to change the soil material of a specific polygon at a specific phase. For instance dogin:
for i in range(len(g_i.Polygons)):
g_i.Polygon[i] g_i.Polygons[i].Soil.Material = material #material includes the soil parameters which are define elsewhere in the code
The code does not work because g_i.Polygons[i] is returning a property and not directing to a specific polygon. See line 390 of the scritp in the zip file.
Looping between phases and changing a specific property of a certain phase that meets a criteria has also no worked.
In summary I guess that I am trying to access propeties when doing g_i.Borehole[i], g_i.Polygons[i] or g_i.Phases[i] than accessing the specific borehole, polygon or phase.
3) I have attached a zip file that contains the Python script that reads the csv files created by an macro saved in the excel file - perhaps the file will help you to understand how vital it is for me to work with loops.
Let me know if you need some further explanation. I am sure that there is a trivial way of doing this but I have not been able to find it.
Best regards, Joao
Boreholes_list.csvJV files.zip
Hi Joao,
In order to set borehole layers from a csv we would need borehole elevation levels, in the script I see that you used thickness data? Is that correct?
Q1 Borehole layers
For the borehole data you could use this:
import csv def read_data(csvfilepath): with open(csvfilepath, 'r') as csvfile: csvdata = csv.reader(csvfile) csvrows = [row for row in csvdata] return csvrows def getboreholelayerinput(cvsline, toplayerindex, isThicknessData=True): """ creates a list with borehole layer elevations :param cvsline: the line from a csv file, a list of values :param toplayerindex: index for the top layer elevation :param isThicknessData: boolean to specify if data is elevation or layer thickness :return: a list of elevation values top-down """ layerlevels = [] # when layer levels are all defined as elevation, use: if isThicknessData is False: layerlevels = [float(i) for i in cvsline[toplayerindex:]] else: # when layer levels are defined as y_level_top, then thinkness values, use: layerlevels = [float(cvsline[toplayerindex])] # create list of elevations. top down for ilvl in range(toplayerindex + 1, len(cvsline)): if 'na' in cvsline[ilvl] or cvsline[ilvl] == '': break else: layerlevels.append(layerlevels[-1] - float(cvsline[ilvl])) return layerlevels def createboreholes(csvfile): """ creates boreholes in a blank project :param csvfile: csv file with borehole data per line, has header line :return: a list of generated boreholes """ csvdata = read_data(csvfile) # column definition from csv file indexName = 1 indexX = 3 indexY = None # 3D only indexHead = 2 indexLayerLevels = 4 # column for yo_top_level # boreholes boreholes = [] for line in csvdata[1:]: # create borehole if indexY: boreholes.append(g_i.borehole(float(line[indexX]), float(line[indexY]))) else: boreholes.append(g_i.borehole(float(line[indexX]))) # set name value boreholes[-1].Name = line[indexName] # set head value boreholes[-1].Head = float(line[indexHead]) #set soil layer levels BHlayerlevels = getboreholelayerinput(line, indexLayerLevels, isThicknessData=False) # make sure we have enough soillayers: adding soillayers for the first borehole if len(boreholes) == 1: for layer in range(len(BHlayerlevels)-1): g_i.soillayer(0) # jsut add zero thickness layers initially, correct later firstborehole = False #set all soil layer levels per borehole: g_i.setsoillayerlevel(boreholes[-1], *[(i, BHlayerlevels[i]) for i in range(len(BHlayerlevels))]) return boreholes # start a new project and add boreholes s_i.new() createboreholes('Boreholes_list.csv')
Q2 Looping over polygons
It seems you are looping over all Polygon names in staged construction. In that case, the Polygon created in Structures mode has been intersected and now we have a cut object. If you use the name of the polygon, we could loop over all the polygon-entities that originate from that original name. And to set materials, you would also need to tell in which phase it needs to be done. Here is a small example
polygonnames = ['PolygonName1', 'PolygonName2'] phase = g_i.Phase_1 material = g_i.MaterialB for pgname in polygonnames: if hasattr(g_i, pgname): pgobject = getattr(g_i, pgname) for cutobject in pgobject: # deactivate polygon: g_i.activate(cutobject, phase) # change material g_i.setmaterial(cutobject, phase, material)
I hope these examples here help to get the script working.
Looks to be an interesting way to automate these model generations.
Kind regards,
Micha
Answer Verified By: Joao Ferreira Verde
Hi Micha,
Thank you for the bits of coding. Those were super helpful to understand how the code should be instruction Plaxis. Now, things are running smoothly.
All the best,