diff --git a/.github/workflows/update-search.yml b/.github/workflows/update-search.yml index 3fb9a3c..3787adf 100644 --- a/.github/workflows/update-search.yml +++ b/.github/workflows/update-search.yml @@ -9,61 +9,29 @@ on: paths: - '**/*.md' - '**/*.html' - - 'scripts/generate_search_db.rb' - - 'scripts/fetch_github_blog_content.js' - - 'scripts/package.json' + - '.github/workflows/update-search.yml' # Add permissions needed for the workflow permissions: contents: write # This allows the action to commit and push changes - packages: read # This allows the action to read from npm jobs: update-search: runs-on: ubuntu-latest - env: - NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - NPM_CONFIG_CACHE: ${{ github.workspace }}/.npm steps: - uses: actions/checkout@v4 with: fetch-depth: 0 # Fetch all history for proper git operations - - name: Set up Ruby - uses: ruby/setup-ruby@v1 - with: - ruby-version: '3.2' - bundler-cache: true - - - name: Set up Node.js - uses: actions/setup-node@v4 - with: - node-version: '20' - cache: 'npm' - cache-dependency-path: 'scripts/package.json' - registry-url: 'https://registry.npmjs.org' - - - name: Install Ruby dependencies + - name: Clone comphy-search repository run: | - gem install bundler - bundle config path vendor/bundle - bundle install - gem install nokogiri + git clone https://github.com/comphy-lab/comphy-search.git + mkdir -p assets/js - - name: Install Node.js dependencies + - name: Copy search database run: | - cd scripts - npm install - - - name: Fetch blog content from GitHub repository - run: | - cd scripts - node fetch_github_blog_content.js - - - name: Generate search database - run: ruby scripts/generate_search_db.rb - + cp comphy-search/search_db.json assets/js/search_db.json - name: Commit and push changes directly (bypassing branch protection) run: | @@ -73,7 +41,7 @@ jobs: if git diff --staged --quiet; then echo "No changes to commit" else - git commit -m "Update search database" + git commit -m "Update search database from comphy-search repository" # Use PAT to bypass branch protection git push https://${{ secrets.BYPASS_TOKEN }}@github.com/${GITHUB_REPOSITORY}.git HEAD:main fi diff --git a/README.md b/README.md index 1471f05..d0464e9 100644 --- a/README.md +++ b/README.md @@ -254,6 +254,12 @@ Search results are prioritized and filtered as follows: - Updated automatically every 12 hours via GitHub Actions 5. Regular content (headings and paragraphs) +The search database is maintained in a separate repository [comphy-lab/comphy-search](https://github.com/comphy-lab/comphy-search) and is automatically updated in this website via GitHub Actions. This approach: +- Centralizes search database generation in a dedicated repository +- Ensures consistent search functionality across the website +- Automatically updates the search database daily or when content changes +- Simplifies maintenance by separating search logic from the website code + ### Command Palette Functionality The website includes a command palette feature that provides quick access to actions and navigation through keyboard shortcuts: @@ -292,20 +298,12 @@ Search behavior and features: - Search results appear instantly as you type - Results are ranked by relevance and match percentage -The search database is automatically generated during the build process by `scripts/generate_search_db.rb`. This script: -- Indexes all HTML and markdown content -- Identifies and prioritizes team members, teaching content, and research papers -- Extracts tags from research papers -- Processes teaching pages and course details -- Fetches and indexes blog posts from blogs.comphy-lab.org -- Generates a JSON database used by the search functionality - ### External Blog Integration The search functionality includes content from our external blog at blogs.comphy-lab.org: -- Blog posts are fetched and indexed during build +- Blog posts are fetched and indexed in the comphy-search repository - Each post's title and content are searchable - Results link directly to the blog post -- Blog content is refreshed with each build +- Blog content is refreshed with each update to the search database ### Tags System Research papers can be tagged with multiple topics. Tags are defined in the markdown files using the following format: @@ -394,10 +392,11 @@ The website uses three GitHub Actions workflows for automation: 3. **Update Search Database** (`.github/workflows/update-search.yml`) - Maintains site's search functionality - Triggers: - - Every 4 hours automatically + - Daily at 4:00 UTC automatically - On content file changes (MD/HTML) - Manual trigger available - - Generates and updates `search_db.json` + - Fetches the search database from [comphy-lab/comphy-search](https://github.com/comphy-lab/comphy-search) + - Updates `search_db.json` in the website repository - Commits changes back to repository These workflows work together to ensure: @@ -405,6 +404,23 @@ These workflows work together to ensure: - Up-to-date search functionality - Consistent deployment to GitHub Pages +3. **Blog Content Indexing** + - Blog content from [blogs.comphy-lab.org](https://blogs.comphy-lab.org) is indexed in the [comphy-search](https://github.com/comphy-lab/comphy-search) repository + - Source: [comphy-lab/CoMPhy-Lab-Blogs](https://github.com/comphy-lab/CoMPhy-Lab-Blogs) + - Filtering criteria: + - Only indexes markdown files where `publish: false` is NOT set in frontmatter + - Automatically excludes any files with "todo" in the filename (case-insensitive) + - The search index is automatically updated: + - Daily via GitHub Actions + - When changes are pushed to markdown or HTML files + - Can be manually triggered from the Actions tab + - This approach improves search quality by: + - Centralizing search database generation + - Accessing the raw markdown directly from the source + - Respecting publish status in frontmatter + - Processing content in a more structured way + - Avoiding web scraping issues or rate limits + ## Contributing ### Issue Templates @@ -436,29 +452,4 @@ To submit a PR: 3. Test changes locally 4. Create a PR using the template 5. Link any related issues -6. Wait for review - -3. **Blog Content Indexing** - - Blog content from [blogs.comphy-lab.org](https://blogs.comphy-lab.org) is now indexed directly from the GitHub repository - - Source: [comphy-lab/CoMPhy-Lab-Blogs](https://github.com/comphy-lab/CoMPhy-Lab-Blogs) - - Filtering criteria: - - Only indexes markdown files where `publish: false` is NOT set in frontmatter - - Automatically excludes any files with "todo" in the filename (case-insensitive) - - The search index is automatically updated: - - Every 12 hours via GitHub Actions - - When changes are pushed to markdown or HTML files - - Can be manually triggered from the Actions tab - - To manually update the search index locally: - ```bash - # From the project root directory - cd scripts - npm install - node fetch_github_blog_content.js - cd .. - ruby scripts/generate_search_db.rb - ``` - - This approach improves search quality by: - - Accessing the raw markdown directly from the source - - Respecting publish status in frontmatter - - Processing content in a more structured way - - Avoiding web scraping issues or rate limits \ No newline at end of file +6. Wait for review \ No newline at end of file diff --git a/assets/js/search_db.json b/assets/js/search_db.json index fbb223e..4fd641e 100644 --- a/assets/js/search_db.json +++ b/assets/js/search_db.json @@ -301,417 +301,665 @@ "priority": 1 }, { - "title": "April", - "content": "- Vatsal Sanjay awarded the Ammodo Science Fellowship. His research will focus on understanding fluid dynamics in fungal networks—investigating how these vast underground systems transport water, nutrients, and genetic information across ecosystems.\n\n
\n
\n
\n \"Vatsal\n
\n
\n Read More\n
\n
\n
\n Image credit: J. Heitman, B. J. Howlett, P. W. Crous, E. H. Stukenbrock, T. Y. James & N. A. R. Gow, The fungal kingdom, John Wiley & Sons (2020)\n
\n
", - "url": "/#about", - "type": "markdown_section", - "priority": 3 - }, - { - "title": "April", - "content": "- Vatsal Sanjay awarded the Ammodo Science Fellowship. His research will focus on understanding fluid dynamics in fungal networks—investigating how these vast underground systems transport water, nutrients, and genetic information across ecosystems.", - "url": "/#about", - "type": "markdown_text", - "priority": 3 - }, - { - "title": "March", - "content": "- Prof. Detlef Lohse shares his scientific journey in The Living Histories Series. His inspiring discussion on curiosity, mentorship, and the \"puzzle solving\" joy of science offers valuable insights for researchers at all career stages.\n\n
\n
\n Watch on YouTube\n
\n
\n\n\n\n- Join us for a hybrid online+offline course: [High-Fidelity Simulations Using Basilisk C](/teaching/2025-Basilisk101-Madrid) in Madrid, Spain (March 10-13). Learn some computational (colorful) fluid dynamics with hands-on coding sessions.", - "url": "/#about", - "type": "markdown_section", - "priority": 3 - }, - { - "title": "March", - "content": "- Prof. Detlef Lohse shares his scientific journey in The Living Histories Series. His inspiring discussion on curiosity, mentorship, and the \"puzzle solving\" joy of science offers valuable insights for researchers at all career stages.", - "url": "/#about", - "type": "markdown_text", - "priority": 3 - }, - { - "title": "March", - "content": "- Join us for a hybrid online+offline course: [High-Fidelity Simulations Using Basilisk C](/teaching/2025-Basilisk101-Madrid) in Madrid, Spain (March 10-13). Learn some computational (colorful) fluid dynamics with hands-on coding sessions.", - "url": "/#about", - "type": "markdown_text", - "priority": 3 - }, - { - "title": "February", - "content": "- [Sanjay, V., Zhang, B., Lv, C., & Lohse, D. J. Fluid Mech., 1004, A6 (2025) selected as the cover article.](/research#14)\n\n
\n
\n
\n \n \"JFM\n \n
\n
\n Download Cover\n View Paper\n
\n
\n
\n\n- Milan Sent \n \n graduated with a bachelor's degree from University of Twente. Thesis: \n \n Spinning Pizza\n ", - "url": "/#about", - "type": "markdown_section", - "priority": 3 - }, - { - "title": "February", - "content": "- [Sanjay, V., Zhang, B., Lv, C., & Lohse, D. J. Fluid Mech., 1004, A6 (2025) selected as the cover article.](/research#14)", - "url": "/#about", - "type": "markdown_text", - "priority": 3 - }, - { - "title": "February", - "content": "- Milan Sent \n \n graduated with a bachelor's degree from University of Twente. Thesis: \n \n Spinning Pizza\n ", - "url": "/#about", - "type": "markdown_text", - "priority": 3 - }, - { - "title": "December", - "content": "[Balasubramanian, A. G., Sanjay, V., Jalaal, M., Vinuesa, R., & Tammisola, O. J. Fluid Mech., 1001, A9 (2024). selected as the cover article.](/research#12)\n\n
\n
\n
\n \n \"JFM\n \n
\n
\n Download Cover\n View Paper\n
\n
\n
", - "url": "/#about", - "type": "markdown_section", - "priority": 3 + "title": "[15]Sanjay, V., & Lohse, D. Unifying theory of scaling in drop impact: Forces & maximum spreading diameter. Phys. Rev. Lett., 134, 104003 (2025).", + "content": "Drops Dissipative anomaly Superamphiphobic-surfaces Impact forces Featured [![PRL](https://img.shields.io/static/v1.svg?style=flat-square&label=PRL&message=OA&color=orange)](https://doi.org/10.1103/PhysRevLett.134.104003) [![arXiv](https://img.shields.io/static/v1.svg?style=flat-square&label=arXiv&message=2408.12714&color=green)](https://arxiv.org/abs/2408.12714) [![GitHub](https://img.shields.io/badge/GitHub-100000?style=flat-square&logo=github&logoColor=white)](https://github.com/VatsalSy/Impact-forces-of-water-drops-falling-on-superhydrophobic-surfaces.git) [![Blog](https://img.shields.io/badge/Blog-Coming%20Soon-yellow?style=flat-square&logo=obsidian&logoColor=white)](https://blogs.comphy-lab.org/0_ToDo-Blog-public) ![Parameter space of drop impact](https://www.dropbox.com/scl/fi/rwrl444r73nayhw1jl4j2/SL2-theory_num.png?rlkey=ekywyjaui2n79djl4qtgevegn&raw=1){: width=\"75%\" .center-block style=\"display: block; margin-left: auto; margin-right: auto;\"}", + "url": "/research/#15", + "type": "paper", + "tags": [ + "Drops", + "Dissipative anomaly", + "Superamphiphobic-surfaces", + "Impact forces", + "Featured" + ], + "priority": 2 }, { - "title": "December", - "content": "[Balasubramanian, A. G., Sanjay, V., Jalaal, M., Vinuesa, R., & Tammisola, O. J. Fluid Mech., 1001, A9 (2024). selected as the cover article.](/research#12)", - "url": "/#about", - "type": "markdown_text", - "priority": 3 + "title": "[14]Sanjay, V., Zhang, B., Lv, C., & Lohse, D. The role of viscosity on drop impact forces on non-wetting surfaces. J. Fluid Mech., 1004, A6 (2025).", + "content": "Drops Impact forces Featured [![JFM](https://img.shields.io/static/v1.svg?style=flat-square&label=JFM&message=OA&color=orange)](https://doi.org/10.1017/jfm.2024.982) [![arXiv](https://img.shields.io/static/v1.svg?style=flat-square&label=arXiv&message=2311.03012&color=green)](https://arxiv.org/abs/2311.03012) [![GitHub](https://img.shields.io/badge/GitHub-100000?style=flat-square&logo=github&logoColor=white)](https://github.com/VatsalSy/The-role-of-viscosity-on-drop-impact-forces) [![Blog](https://img.shields.io/badge/Blog-Coming%20Soon-yellow?style=flat-square&logo=obsidian&logoColor=white)](https://blogs.comphy-lab.org/Blog/2025-JFM-viscous-drop-impact) #### Highlights * Cover of that volume of J. Fluid Mech.", + "url": "/research/#14", + "type": "paper", + "tags": [ + "Drops", + "Impact forces", + "Featured" + ], + "priority": 2 }, { - "title": "November", - "content": "Vatsal Sanjay recognized as an Outstanding Reviewer 2023 by the Journal of Fluid Mechanics for his contributions to the peer review process.", - "url": "/#about", - "type": "markdown_section", + "title": "[13]Kayal, L., Sanjay, V., Yewale, N., Kumar, A., & Dasgupta, R. Focusing of concentric free-surface waves. J. Fluid Mech., 1003, A14 (2025).", + "content": "Waves Dissipative anomaly [![JFM](https://img.shields.io/static/v1.svg?style=flat-square&label=JFM&message=OA&color=orange)](https://doi.org/10.1017/jfm.2024.1089) [![arXiv](https://img.shields.io/static/v1.svg?style=flat-square&label=arXiv&message=2406.05416&color=green)](https://arxiv.org/abs/2406.05416) [![GitHub](https://img.shields.io/badge/GitHub-100000?style=flat-square&logo=github&logoColor=white)](https://github.com/comphy-lab/concentricWave) [![Blog](https://img.shields.io/badge/Blog-Coming%20Soon-yellow?style=flat-square&logo=obsidian&logoColor=white)](https://blogs.comphy-lab.org/0_ToDo-Blog-public) ## 2024", + "url": "/research/#13", + "type": "paper", + "tags": [ + "Waves", + "Dissipative anomaly" + ], "priority": 3 }, { - "title": "May", - "content": "Vatsal Sanjay awarded the KIVI Hoogendoorn Fluid Mechanics Award 2023 for his PhD thesis \"Viscous Free-Surface Flows\". The award ceremony took place at the Burgers Symposium on 29–30 May 2024 in Lunteren.", - "url": "/#about", - "type": "markdown_section", + "title": "[12]Balasubramanian, A. G., Sanjay, V., Jalaal, M., Vinuesa, R., & Tammisola, O. Bursting bubble in an elastoviscoplastic medium. J. Fluid Mech., 1001, A9 (2024).", + "content": "Bubbles Non-Newtonian Jets Soft-matter-singularities [![JFM](https://img.shields.io/static/v1.svg?style=flat-square&label=JFM&message=OA&color=orange)](https://doi.org/10.1017/jfm.2024.1073) [![GitHub](https://img.shields.io/badge/GitHub-100000?style=flat-square&logo=github&logoColor=white)](https://github.com/comphy-lab/2023_Bubble-bursting-in-an-elasto-viscoplastic-medium) [![Blog](https://img.shields.io/badge/Blog-Coming%20Soon-yellow?style=flat-square&logo=obsidian&logoColor=white)](https://blogs.comphy-lab.org/0_ToDo-Blog-public) #### Highlights * Cover of that volume of J. Fluid Mech. ## 2023", + "url": "/research/#12", + "type": "paper", + "tags": [ + "Bubbles", + "Non-Newtonian", + "Jets", + "Soft-matter-singularities" + ], "priority": 3 }, { - "title": "About Us", - "content": "We are based at the Physics of Fluids Department at the University of Twente, where we investigate [**non-Newtonian free-surface flows**](/research/?tag=Non-Newtonian) and [**soft matter singularities**](/research/?tag=Soft-matter-singularities). Our group employs a synergy of continuum simulations, experiments (through collaborations), and theoretical analysis to understand phenomena ranging involving drops, bubbles, jets, sheets, and more. We strive to connect fundamental findings with real-world applications, from industrial processes to everyday fluid dynamics.", - "url": "/#about", - "type": "markdown_section", + "title": "[11]Sanjay, V., Chantelot, P., & Lohse, D. When does an impacting drop stop bouncing? J. Fluid Mech., 958, A26 (2023).", + "content": "Drops Bouncing Dissipative anomaly [![JFM](https://img.shields.io/static/v1.svg?style=flat-square&label=JFM&message=OA&color=orange)](https://doi.org/10.1017/jfm.2023.55) [![Blog](https://img.shields.io/badge/Blog-Coming%20Soon-yellow?style=flat-square&logo=obsidian&logoColor=white)](https://blogs.comphy-lab.org/0_ToDo-Blog-public)", + "url": "/research/#11", + "type": "paper", + "tags": [ + "Drops", + "Bouncing", + "Dissipative anomaly" + ], "priority": 3 }, { - "title": "About Us", - "content": "We are based at the Physics of Fluids Department at the University of Twente, where we investigate [**non-Newtonian free-surface flows**](/research/?tag=Non-Newtonian) and [**soft matter singularities**](/research/?tag=Soft-matter-singularities). Our group employs a synergy of continuum simulations, experiments (through collaborations), and theoretical analysis to understand phenomena ranging involving drops, bubbles, jets, sheets, and more. We strive to connect fundamental findings with real-world applications, from industrial processes to everyday fluid dynamics.", - "url": "/#about", - "type": "markdown_text", + "title": "[10]Sanjay, V., Lakshman, S., Chantelot, P., Snoeijer, J. H., & Lohse, D. Drop impact on viscous liquid films. J. Fluid Mech., 958, A25 (2023).", + "content": "Drops Bouncing Superhydrophobic surfaces [![JFM](https://img.shields.io/static/v1.svg?style=flat-square&label=JFM&message=OA&color=orange)](https://doi.org/10.1017/jfm.2023.13) [![Blog](https://img.shields.io/badge/Blog-Coming%20Soon-yellow?style=flat-square&logo=obsidian&logoColor=white)](https://blogs.comphy-lab.org/0_ToDo-Blog-public) ## 2022", + "url": "/research/#10", + "type": "paper", + "tags": [ + "Drops", + "Bouncing", + "Superhydrophobic surfaces" + ], "priority": 3 }, { - "title": "Soft Matter Singularities", - "content": "We examine topological transitions in fluid systems—such as [**droplet impact**](/research/?tag=Drops), [**bubble bursting**](/research/?tag=Bubbles), and [**sheet fragmentation**](/research/?tag=Sheets) — where local instabilities drive fast, often dramatic flow dynamics. Our goal is to expose the universal mechanisms governing these [**singular**]((/research/?tag=Soft-matter-singularities)) events in soft matter.", - "url": "/#about", - "type": "markdown_section", + "title": "[9]Sanjay, V. Taylor--Culick retractions and the influence of the surroundings. J. Fluid Mech., 948, A14 (2022).", + "content": "Sheets Dissipative anomaly Retraction [![JFM](https://img.shields.io/static/v1.svg?style=flat-square&label=JFM&message=OA&color=orange)](https://doi.org/10.1017/jfm.2022.671) [![Blog](https://img.shields.io/badge/Blog-Coming%20Soon-yellow?style=flat-square&logo=obsidian&logoColor=white)](https://blogs.comphy-lab.org/0_ToDo-Blog-public)", + "url": "/research/#9", + "type": "paper", + "tags": [ + "Sheets", + "Dissipative anomaly", + "Retraction" + ], "priority": 3 }, { - "title": "Soft Matter Singularities", - "content": "We examine topological transitions in fluid systems—such as [**droplet impact**](/research/?tag=Drops), [**bubble bursting**](/research/?tag=Bubbles), and [**sheet fragmentation**](/research/?tag=Sheets) — where local instabilities drive fast, often dramatic flow dynamics. Our goal is to expose the universal mechanisms governing these [**singular**]((/research/?tag=Soft-matter-singularities)) events in soft matter.", - "url": "/#about", - "type": "markdown_text", + "title": "[8]Zhang, B., Sanjay, V., Shi, S., and Zhao, Y., and Lv, C., and Feng, X.-Q., & Lohse, D. Impact forces of water drops falling on superhydrophobic surfaces. Phys. Rev. Lett., 129(10), 104501 (2022).", + "content": "Drops Superhydrophobic surfaces Impact forces [![GitHub](https://img.shields.io/badge/GitHub-100000?style=flat-square&logo=github&logoColor=white)](https://github.com/VatsalSy/Impact-forces-of-water-drops-falling-on-superhydrophobic-surfaces) [![PDF](https://img.shields.io/static/v1.svg?logo=adobeacrobatreader&style=flat-square&label=PDF&message=Download&color=green)](https://qrco.de/bd9aV3) [![arXiv](https://img.shields.io/static/v1.svg?style=flat-square&label=arXiv&message=2202.02437&color=green)](https://arxiv.org/abs/2202.02437) [![DOI](https://img.shields.io/static/v1.svg?style=flat-square&label=Phys.%20Rev.%20Lett.&message=DOI:%2010.1103/PhysRevLett.129.104501&color=orange)](https://doi.org/10.1103/PhysRevLett.129.104501) [![Blog](https://img.shields.io/badge/Blog-Coming%20Soon-yellow?style=flat-square&logo=obsidian&logoColor=white)](https://blogs.comphy-lab.org/0_ToDo-Blog-public) #### Highlights * As of March/April 2024, this highly cited paper received enough citations to place it in the top 1% of the academic field of Physics based on a highly cited threshold for the field and publication year. Source: Web of Science. * Editor's Suggestion of that issue of Phys. Rev. Lett. * Research Highlight: Castelvecchi, D. The physics of a bouncing droplet's impact. _Nature_, 609, 225 (2022). [![DOI](https://img.shields.io/static/v1.svg?style=flat-square&label=DOI:&message=10.1038/d41586-022-02302-w&color=green)](https://doi.org/10.1038/d41586-022-02302-w) ## 2021", + "url": "/research/#8", + "type": "paper", + "tags": [ + "Drops", + "Superhydrophobic surfaces", + "Impact forces" + ], "priority": 3 }, { - "title": "Non-Newtonian Flows as the `Drosophila' of Continuum Mechanics", - "content": "From [**elastoviscoplastic**]((/research/?tag=Non-Newtonian)) bubble bursting and elastic sheet break-up to champagne [**bubble**](/research/?tag=Bubbles) bursting and classical Taylor–Culick retractions, non-Newtonian fluids serve as model systems to explore the fundamentals of continuum mechanics. By integrating high-fidelity simulations, analytical frameworks, and collaborative experiments, we reveal how microstructural stresses affect fluid and solid dynamics. This research provides key insights for industrial and environmental applications.", - "url": "/#about", - "type": "markdown_section", + "title": "[7]Sanjay, V., Lohse, D., & Jalaal, M. Bursting bubble in a viscoplastic medium. J. Fluid Mech., 922, A2 (2021).", + "content": "Bubbles Jets Non-Newtonian Soft-matter-singularities [![JFM](https://img.shields.io/static/v1.svg?style=flat-square&label=JFM&message=OA&color=orange)](https://doi.org/10.1017/jfm.2021.489) [![arXiv](https://img.shields.io/badge/arXiv-2101.07744-green?style=flat-square)](https://arxiv.org/abs/2101.07744) [![GitHub](https://img.shields.io/badge/GitHub-100000?style=flat-square&logo=github&logoColor=white)](https://github.com/VatsalSy/Bursting-Bubble-In-a-Viscoplastic-Medium) [![Blog](https://img.shields.io/badge/Blog-Coming%20Soon-yellow?style=flat-square&logo=obsidian&logoColor=white)](https://blogs.comphy-lab.org/0_ToDo-Blog-public) ## 2020", + "url": "/research/#7", + "type": "paper", + "tags": [ + "Bubbles", + "Jets", + "Non-Newtonian", + "Soft-matter-singularities" + ], "priority": 3 }, { - "title": "Non-Newtonian Flows as the `Drosophila' of Continuum Mechanics", - "content": "From [**elastoviscoplastic**]((/research/?tag=Non-Newtonian)) bubble bursting and elastic sheet break-up to champagne [**bubble**](/research/?tag=Bubbles) bursting and classical Taylor–Culick retractions, non-Newtonian fluids serve as model systems to explore the fundamentals of continuum mechanics. By integrating high-fidelity simulations, analytical frameworks, and collaborative experiments, we reveal how microstructural stresses affect fluid and solid dynamics. This research provides key insights for industrial and environmental applications.", - "url": "/#about", - "type": "markdown_text", + "title": "[6]Ramírez-Soto, O., Sanjay, V., Lohse, D., Pham, J. T., & Vollmer, D. Lifting a sessile oil drop from a superamphiphobic surface with an impacting one. Sci. Adv., 6(34), eaba4330 (2020).", + "content": "Drops Superamphiphobic-surfaces Lifting [![Sci. Adv.](https://img.shields.io/static/v1.svg?style=flat-square&label=Sci.%20Adv.&message=OA&color=orange)](https://doi.org/10.1126/sciadv.aba4330) [![arXiv](https://img.shields.io/badge/arXiv-1912.02667-green?style=flat-square)](https://arxiv.org/abs/1912.02667) [![GitHub](https://img.shields.io/badge/GitHub-100000?style=flat-square&logo=github&logoColor=white)](https://github.com/VatsalSy/Lifting-a-sessile-drop) [![Blog](https://img.shields.io/badge/Blog-Coming%20Soon-yellow?style=flat-square&logo=obsidian&logoColor=white)](https://blogs.comphy-lab.org/0_ToDo-Blog-public) ## 2019", + "url": "/research/#6", + "type": "paper", + "tags": [ + "Drops", + "Superamphiphobic-surfaces", + "Lifting" + ], "priority": 3 }, { - "title": "Viscous Free-Surface Flows", - "content": "We investigate various viscous free-surface flows including inertial contact lines, [**bubble**](/research/?tag=Bubbles) removal, and focusing of [**waves**](/research/?tag=Waves). These phenomena are critical to energy transitions and manufacturing. For instance, a key challenge is optimizing bubble detachment in electrolysis to boost efficiency. This research involves advanced numerical methods and industry partnerships, with the broader aim of advancing technologies from chemical reactors to printing processes.", - "url": "/#about", - "type": "markdown_section", + "title": "[5]Jain, A., Sanjay, V., & Das, A. K. Consequences of inclined and dual jet impingement in stagnant liquid and stratified layers. AIChE J., 65(1), 372-384 (2019).", + "content": "Jets Bubbles [![PDF](https://img.shields.io/static/v1.svg?style=flat-square&label=PDF&message=Available&color=green)](https://www.dropbox.com/s/ug7njhulcy9zq8lib911j/2019-Vatsal-_Consequences-of-Inclined-and-Dual-Jet-Impingement-in-Stagnant-Liquid-and-Stratified-Layers.pdf?rlkey=l00thknv7wt55sb0bcuiy8isw&dl=0) [![DOI](https://img.shields.io/static/v1.svg?style=flat-square&label=DOI&message=10.1002/aic.16373&color=orange)](https://doi.org/10.1002/aic.16373) [![Blog](https://img.shields.io/badge/Blog-Coming%20Soon-yellow?style=flat-square&logo=obsidian&logoColor=white)](https://blogs.comphy-lab.org/0_ToDo-Blog-public) ## 2018", + "url": "/research/#5", + "type": "paper", + "tags": [ + "Jets", + "Bubbles" + ], "priority": 3 }, { - "title": "Viscous Free-Surface Flows", - "content": "We investigate various viscous free-surface flows including inertial contact lines, [**bubble**](/research/?tag=Bubbles) removal, and focusing of [**waves**](/research/?tag=Waves). These phenomena are critical to energy transitions and manufacturing. For instance, a key challenge is optimizing bubble detachment in electrolysis to boost efficiency. This research involves advanced numerical methods and industry partnerships, with the broader aim of advancing technologies from chemical reactors to printing processes.", - "url": "/#about", - "type": "markdown_text", + "title": "[4]Soni, A., Sanjay, V., & Das, A. K. Formation of fluid structures due to jet-jet and jet-sheet interactions. Chem. Eng. Sci., 191, 67-77 (2018).", + "content": "Jets [![PDF](https://img.shields.io/static/v1.svg?style=flat-square&label=PDF&message=Available&color=green)](https://www.dropbox.com/s/ranuyet8h7nub3s/%5B2018-Vatsal-preprint%5D_Formation%20of%20fluid%20structures%20due%20to%20jet-jet%20and%20jet-sheet%20interactions.pdf?dl=0) [![DOI](https://img.shields.io/static/v1.svg?style=flat-square&label=DOI&message=10.1016/j.ces.2018.06.055&color=orange)](https://doi.org/10.1016/j.ces.2018.06.055) [![Blog](https://img.shields.io/badge/Blog-Coming%20Soon-yellow?style=flat-square&logo=obsidian&logoColor=white)](https://blogs.comphy-lab.org/0_ToDo-Blog-public)", + "url": "/research/#4", + "type": "paper", + "tags": [ + "Jets" + ], "priority": 3 }, { - "title": "Commitment to Open Science", - "content": "Open exchange of ideas drives our progress. We share our codes from the earliest stages of development, embracing transparent research practices to foster collaboration and reproducibility. We welcome inquiries and partnerships from the broader scientific community. Watchout for [![GitHub](https://img.shields.io/badge/GitHub-100000?style=flat-square&logo=github&logoColor=white)](https://github.com/comphy-lab) and [](https://github.com/comphy-lab \"Visit our GitHub organization\") on this website to interact with our codes. \n\nFeel free to contact us for discussions about our work or anything else related to fluid physics. Nothing is more exhilarating than a healthy scientific discussion.", - "url": "/#about", - "type": "markdown_section", + "title": "[3]Sanjay, V., Das, A.K. Numerical assessment of hazard in compartmental fire having steady heat release rate from the source. Build. Simul. 11, 613–624 (2018).", + "content": "Others Fire Evacuation [![PDF](https://img.shields.io/static/v1.svg?style=flat-square&label=PDF&message=Available&color=green)](https://www.dropbox.com/s/6kfiem9zcvjr2vf/%5B2018-Vatsal%5D_Numerical%20assessment%20of%20hazard%20in%20compartmental%20fire%20having%20steady%20heat%20release%20rate%20from%20the%20source.pdf?dl=0) [![DOI](https://img.shields.io/static/v1.svg?style=flat-square&label=DOI&message=10.1007/s12273-017-0411-y&color=orange)](https://doi.org/10.1007/s12273-017-0411-y) [![Blog](https://img.shields.io/badge/Blog-Coming%20Soon-yellow?style=flat-square&logo=obsidian&logoColor=white)](https://blogs.comphy-lab.org/0_ToDo-Blog-public) ## 2017", + "url": "/research/#3", + "type": "paper", + "tags": [ + "Others", + "Fire", + "Evacuation" + ], "priority": 3 }, { - "title": "Commitment to Open Science", - "content": "Open exchange of ideas drives our progress. We share our codes from the earliest stages of development, embracing transparent research practices to foster collaboration and reproducibility. We welcome inquiries and partnerships from the broader scientific community. Watchout for [![GitHub](https://img.shields.io/badge/GitHub-100000?style=flat-square&logo=github&logoColor=white)](https://github.com/comphy-lab) and [](https://github.com/comphy-lab \"Visit our GitHub organization\") on this website to interact with our codes.", - "url": "/#about", - "type": "markdown_text", + "title": "[2]Sanjay, V., & Das, A. K. Formation of liquid chain by collision of two laminar jets. Phys. Fluids, 29(11), 112101 (2017).", + "content": "Jets Sheets [![PDF](https://img.shields.io/static/v1.svg?style=flat-square&label=PDF&message=Available&color=green)](https://www.dropbox.com/s/e9uo0hcrm9es8hr/%5B2017-Vatsal-preprint%5D_Formation%20of%20liquid%20chain%20by%20collision%20of%20two%20laminar%20jets.pdf?dl=0) [![DOI](https://img.shields.io/static/v1.svg?style=flat-square&label=DOI&message=10.1063/1.4998288&color=orange)](https://doi.org/10.1063/1.4998288) [![GitHub](https://img.shields.io/badge/GitHub-100000?style=flat-square&logo=github&logoColor=white)](https://github.com/VatsalSy/FluidChains) [![Blog](https://img.shields.io/badge/Blog-Coming%20Soon-yellow?style=flat-square&logo=obsidian&logoColor=white)](https://blogs.comphy-lab.org/0_ToDo-Blog-public)", + "url": "/research/#2", + "type": "paper", + "tags": [ + "Jets", + "Sheets" + ], "priority": 3 }, { - "title": "Commitment to Open Science", - "content": "Feel free to contact us for discussions about our work or anything else related to fluid physics. Nothing is more exhilarating than a healthy scientific discussion.", - "url": "/#about", - "type": "markdown_text", - "priority": 3 - }, - { - "title": "Location & Website", - "content": "[![Location](https://img.shields.io/badge/-Physics%20of%20Fluids-4285F4?style=flat&logo=googlemaps&logoColor=white)](https://maps.app.goo.gl/jSTCYnfcndF1uZPV8)\n[![Website](https://img.shields.io/badge/-comphy--lab.org-4285F4?style=flat&logo=googlechrome&logoColor=white)](http://www.comphy-lab.org)\n[![Email](https://img.shields.io/badge/-mailto:vatsalsy@comphy--lab.org-EA4335?style=flat&logo=gmail&logoColor=white)](mailto:vatsalsy@comphy-lab.org)\n\n
\n vatsalsy@comphy-lab.org\n \n
", - "url": "/#about", - "type": "markdown_section", - "priority": 3 - }, - { - "title": "Location & Website", - "content": "[![Location](https://img.shields.io/badge/-Physics%20of%20Fluids-4285F4?style=flat&logo=googlemaps&logoColor=white)](https://maps.app.goo.gl/jSTCYnfcndF1uZPV8)\n[![Website](https://img.shields.io/badge/-comphy--lab.org-4285F4?style=flat&logo=googlechrome&logoColor=white)](http://www.comphy-lab.org)\n[![Email](https://img.shields.io/badge/-mailto:vatsalsy@comphy--lab.org-EA4335?style=flat&logo=gmail&logoColor=white)](mailto:vatsalsy@comphy-lab.org)", - "url": "/#about", - "type": "markdown_text", - "priority": 3 - }, - { - "title": "Academic Profiles", - "content": "[![Google Scholar](https://img.shields.io/badge/-Google%20Scholar-4285F4?style=flat&logo=googlescholar&logoColor=white)](https://scholar.google.com/citations?user=tHb_qZoAAAAJ&hl=en)\n[![ORCID](https://img.shields.io/badge/-ORCID-A6CE39?style=flat&logo=orcid&logoColor=white)](https://orcid.org/0000-0002-4293-6099)\n[![arXiv](https://img.shields.io/badge/-arXiv-B31B1B?style=flat&logo=arxiv&logoColor=white)](https://arxiv.org/search/?query=vatsal+sanjay&searchtype=all&source=header)\n[![ResearchGate](https://img.shields.io/badge/-ResearchGate-00CCBB?style=flat&logo=researchgate&logoColor=white)](https://www.researchgate.net/profile/Vatsal-Sanjay-2)", - "url": "/#about", - "type": "markdown_section", - "priority": 3 - }, - { - "title": "Academic Profiles", - "content": "[![Google Scholar](https://img.shields.io/badge/-Google%20Scholar-4285F4?style=flat&logo=googlescholar&logoColor=white)](https://scholar.google.com/citations?user=tHb_qZoAAAAJ&hl=en)\n[![ORCID](https://img.shields.io/badge/-ORCID-A6CE39?style=flat&logo=orcid&logoColor=white)](https://orcid.org/0000-0002-4293-6099)\n[![arXiv](https://img.shields.io/badge/-arXiv-B31B1B?style=flat&logo=arxiv&logoColor=white)](https://arxiv.org/search/?query=vatsal+sanjay&searchtype=all&source=header)\n[![ResearchGate](https://img.shields.io/badge/-ResearchGate-00CCBB?style=flat&logo=researchgate&logoColor=white)](https://www.researchgate.net/profile/Vatsal-Sanjay-2)", - "url": "/#about", - "type": "markdown_text", - "priority": 3 - }, - { - "title": "Social Media", - "content": "[![X](https://img.shields.io/badge/-@CoMPhyLab-000000?style=flat&logo=x&logoColor=white)](https://twitter.com/VatsalSanjay)\n[![Bluesky](https://img.shields.io/badge/-@comphy--lab.org-0285FF?style=flat&logo=bluesky&logoColor=white)](https://bsky.app/profile/comphy-lab.org)\n\nFor supplementary videos and teaser of our upcoming work:\n\n\n \"Vatsal's\n \"Vatsal's\n", - "url": "/#about", - "type": "markdown_section", - "priority": 3 - }, - { - "title": "Social Media", - "content": "[![X](https://img.shields.io/badge/-@CoMPhyLab-000000?style=flat&logo=x&logoColor=white)](https://twitter.com/VatsalSanjay)\n[![Bluesky](https://img.shields.io/badge/-@comphy--lab.org-0285FF?style=flat&logo=bluesky&logoColor=white)](https://bsky.app/profile/comphy-lab.org)", - "url": "/#about", - "type": "markdown_text", + "title": "[1]Sanjay, V., & Das, A. K. On air entrainment in a water pool by impingement of a jet. AIChE J., 63(11), 5169-5181 (2017).", + "content": "Jets Bubbles [![PDF](https://img.shields.io/static/v1.svg?style=flat-square&label=PDF&message=Available&color=green)](https://www.dropbox.com/s/bm49xi8ic6i3icf/%5B2017-Vatsal-preprint%5D_On%20Air%20Entrainment%20in%20a%20Water%20pool%20by%20Impingement%20of%20a%20Jet.pdf?dl=0) [![DOI](https://img.shields.io/static/v1.svg?style=flat-square&label=DOI&message=10.1002/aic.15828&color=orange)](https://doi.org/10.1002/aic.15828) [![Blog](https://img.shields.io/badge/Blog-Coming%20Soon-yellow?style=flat-square&logo=obsidian&logoColor=white)](https://blogs.comphy-lab.org/0_ToDo-Blog-public)", + "url": "/research/#1", + "type": "paper", + "tags": [ + "Jets", + "Bubbles" + ], "priority": 3 }, { "title": "\"High-Fidelity Simulations Using Basilisk C\" - High-Fidelity Simulations Using Basilisk C", - "content": "
\n
\n

Dates

\n

March 10-13, 2025

\n
\n
\n

Location

\n

Universidad Carlos III de Madrid, Spain

\n
\n
\n

Duration

\n

4 days, full-time

\n
\n
", + "content": "Dates March 10-13, 2025 Location Universidad Carlos III de Madrid, Spain Duration 4 days, full-time", "url": "/teaching/2025-Basilisk101-Madrid#High-Fidelity%2BSimulations%2BUsing%2BBasilisk%2BC", "type": "teaching_content", "priority": 2 }, { "title": "\"High-Fidelity Simulations Using Basilisk C\" - What will you learn?", - "content": "- **Think before you compute!** Understanding the physics before implementation\n- **Writing the first code in Basilisk C** Getting comfortable with the framework\n- **Solving conservation equations** Numerical approaches to fluid dynamics\n- **Interface tracking methods** Capturing multiphase phenomena accurately\n- **Non-Newtonian flows** Modeling complex rheological behaviors", + "content": "- **Think before you compute!** Understanding the physics before implementation - **Writing the first code in Basilisk C** Getting comfortable with the framework - **Solving conservation equations** Numerical approaches to fluid dynamics - **Interface tracking methods** Capturing multiphase phenomena accurately - **Non-Newtonian flows** Modeling complex rheological behaviors", "url": "/teaching/2025-Basilisk101-Madrid#What%2Bwill%2Byou%2Blearn", "type": "teaching_content", "priority": 2 }, { "title": "\"High-Fidelity Simulations Using Basilisk C\" - What will you learn?", - "content": "- **Think before you compute!** Understanding the physics before implementation\n- **Writing the first code in Basilisk C** Getting comfortable with the framework\n- **Solving conservation equations** Numerical approaches to fluid dynamics\n- **Interface tracking methods** Capturing multiphase phenomena accurately\n- **Non-Newtonian flows** Modeling complex rheological behaviors", + "content": "- **Think before you compute!** Understanding the physics before implementation - **Writing the first code in Basilisk C** Getting comfortable with the framework - **Solving conservation equations** Numerical approaches to fluid dynamics - **Interface tracking methods** Capturing multiphase phenomena accurately - **Non-Newtonian flows** Modeling complex rheological behaviors", "url": "/teaching/2025-Basilisk101-Madrid#What%2Bwill%2Byou%2Blearn", "type": "teaching_paragraph", "priority": 2 }, { "title": "\"High-Fidelity Simulations Using Basilisk C\" - Course Description", - "content": "This intensive 4-day course provides a comprehensive introduction to high-fidelity simulations using Basilisk C, a powerful computational framework for fluid dynamics. Participants will learn to implement and solve complex fluid mechanics problems with an emphasis on multiphase flows, interface dynamics, and non-Newtonian rheology.\n\nThe course combines theoretical lectures with extensive hands-on sessions, allowing participants to immediately apply concepts through guided coding exercises. By the end of the course, you'll be able to develop your own simulations for a variety of fluid dynamics applications.", + "content": "This intensive 4-day course provides a comprehensive introduction to high-fidelity simulations using Basilisk C, a powerful computational framework for fluid dynamics. Participants will learn to implement and solve complex fluid mechanics problems with an emphasis on multiphase flows, interface dynamics, and non-Newtonian rheology. The course combines theoretical lectures with extensive hands-on sessions, allowing participants to immediately apply concepts through guided coding exercises. By the end of the course, you'll be able to develop your own simulations for a variety of fluid dynamics applications.", "url": "/teaching/2025-Basilisk101-Madrid#Course%2BDescription", "type": "teaching_content", "priority": 2 }, { "title": "\"High-Fidelity Simulations Using Basilisk C\" - Course Description", - "content": "This intensive 4-day course provides a comprehensive introduction to high-fidelity simulations using Basilisk C, a powerful computational framework for fluid dynamics. Participants will learn to implement and solve complex fluid mechanics problems with an emphasis on multiphase flows, interface dynamics, and non-Newtonian rheology.", - "url": "/teaching/2025-Basilisk101-Madrid#Course%2BDescription", - "type": "teaching_paragraph", - "priority": 2 - }, - { - "title": "\"High-Fidelity Simulations Using Basilisk C\" - Course Description", - "content": "The course combines theoretical lectures with extensive hands-on sessions, allowing participants to immediately apply concepts through guided coding exercises. By the end of the course, you'll be able to develop your own simulations for a variety of fluid dynamics applications.", + "content": "This intensive 4-day course provides a comprehensive introduction to high-fidelity simulations using Basilisk C, a powerful computational framework for fluid dynamics. Participants will learn to implement and solve complex fluid mechanics problems with an emphasis on multiphase flows, interface dynamics, and non-Newtonian rheology. The course combines theoretical lectures with extensive hands-on sessions, allowing participants to immediately apply concepts through guided coding exercises. By the end of the course, you'll be able to develop your own simulations for a variety of fluid dynamics applications.", "url": "/teaching/2025-Basilisk101-Madrid#Course%2BDescription", "type": "teaching_paragraph", "priority": 2 }, { "title": "\"High-Fidelity Simulations Using Basilisk C\" - Think before you compute", - "content": "- **10:00-11:30**  |  **Lecture (1a)**\n - Conservation laws and the numerical solution of the Navier–Stokes equations\n- **11:45-13:00**  |  **Lecture (1b)**\n - Transport equations\n - *Brief intro to Basilisk coding framework*", + "content": "- **10:00-11:30**  |  **Lecture (1a)** - Conservation laws and the numerical solution of the Navier–Stokes equations - **11:45-13:00**  |  **Lecture (1b)** - Transport equations - *Brief intro to Basilisk coding framework*", "url": "/teaching/2025-Basilisk101-Madrid#Think%2Bbefore%2Byou%2Bcompute", "type": "teaching_content", "priority": 2 }, { "title": "\"High-Fidelity Simulations Using Basilisk C\" - Think before you compute", - "content": "- **10:00-11:30**  |  **Lecture (1a)**\n - Conservation laws and the numerical solution of the Navier–Stokes equations\n- **11:45-13:00**  |  **Lecture (1b)**\n - Transport equations\n - *Brief intro to Basilisk coding framework*", + "content": "- **10:00-11:30**  |  **Lecture (1a)** - Conservation laws and the numerical solution of the Navier–Stokes equations - **11:45-13:00**  |  **Lecture (1b)** - Transport equations - *Brief intro to Basilisk coding framework*", "url": "/teaching/2025-Basilisk101-Madrid#Think%2Bbefore%2Byou%2Bcompute", "type": "teaching_paragraph", "priority": 2 }, { "title": "\"High-Fidelity Simulations Using Basilisk C\" - First coding steps", - "content": "- **15:00-18:00**  |  **Hybrid Session**\n - Implementing basic transport equations in Basilisk C.\n - Using headers in Basilisk, modular code structure, problem setup, and compilation\n - *Whiteboard + coding*\n - [1st Working Assignment](https://blogs.comphy-lab.org/Lecture-Notes/Basilisk101/1st-workingAssignment)", + "content": "- **15:00-18:00**  |  **Hybrid Session** - Implementing basic transport equations in Basilisk C. - Using headers in Basilisk, modular code structure, problem setup, and compilation - *Whiteboard + coding* - [1st Working Assignment](https://blogs.comphy-lab.org/Lecture-Notes/Basilisk101/1st-workingAssignment)", "url": "/teaching/2025-Basilisk101-Madrid#First%2Bcoding%2Bsteps", "type": "teaching_content", "priority": 2 }, { "title": "\"High-Fidelity Simulations Using Basilisk C\" - First coding steps", - "content": "- **15:00-18:00**  |  **Hybrid Session**\n - Implementing basic transport equations in Basilisk C.\n - Using headers in Basilisk, modular code structure, problem setup, and compilation\n - *Whiteboard + coding*\n - [1st Working Assignment](https://blogs.comphy-lab.org/Lecture-Notes/Basilisk101/1st-workingAssignment)", + "content": "- **15:00-18:00**  |  **Hybrid Session** - Implementing basic transport equations in Basilisk C. - Using headers in Basilisk, modular code structure, problem setup, and compilation - *Whiteboard + coding* - [1st Working Assignment](https://blogs.comphy-lab.org/Lecture-Notes/Basilisk101/1st-workingAssignment)", "url": "/teaching/2025-Basilisk101-Madrid#First%2Bcoding%2Bsteps", "type": "teaching_paragraph", "priority": 2 }, { "title": "\"High-Fidelity Simulations Using Basilisk C\" - Coding like a pro", - "content": "- **10:00-11:15**  |  **Hackathon (1c)**\n - Solving Navier–Stokes equations in Basilisk C. \n - [2nd Working Assignment](https://blogs.comphy-lab.org/Lecture-Notes/Basilisk101/2nd-workingAssignment)\n- **11:30-13:00**  |  **Hackathon Continued**\n - Expanding on the morning tasks and code debugging", + "content": "- **10:00-11:15**  |  **Hackathon (1c)** - Solving Navier–Stokes equations in Basilisk C. - [2nd Working Assignment](https://blogs.comphy-lab.org/Lecture-Notes/Basilisk101/2nd-workingAssignment) - **11:30-13:00**  |  **Hackathon Continued** - Expanding on the morning tasks and code debugging", "url": "/teaching/2025-Basilisk101-Madrid#Coding%2Blike%2Ba%2Bpro", "type": "teaching_content", "priority": 2 }, { "title": "\"High-Fidelity Simulations Using Basilisk C\" - Coding like a pro", - "content": "- **10:00-11:15**  |  **Hackathon (1c)**\n - Solving Navier–Stokes equations in Basilisk C. \n - [2nd Working Assignment](https://blogs.comphy-lab.org/Lecture-Notes/Basilisk101/2nd-workingAssignment)\n- **11:30-13:00**  |  **Hackathon Continued**\n - Expanding on the morning tasks and code debugging", + "content": "- **10:00-11:15**  |  **Hackathon (1c)** - Solving Navier–Stokes equations in Basilisk C. - [2nd Working Assignment](https://blogs.comphy-lab.org/Lecture-Notes/Basilisk101/2nd-workingAssignment) - **11:30-13:00**  |  **Hackathon Continued** - Expanding on the morning tasks and code debugging", "url": "/teaching/2025-Basilisk101-Madrid#Coding%2Blike%2Ba%2Bpro", "type": "teaching_paragraph", "priority": 2 }, { "title": "\"High-Fidelity Simulations Using Basilisk C\" - Interface tracking methods", - "content": "- **10:00-11:30**  |  **Lecture (2a)**\n - Interface tracking methods (VoF, level set, phase-field approaches) and numerical strategies\n- **11:45-13:00**  |  **Hackathon (2b)**\n - Hands-on tutorial with interface-tracking to a simple two-phase problem\n - [3rd Working Assignment](https://blogs.comphy-lab.org/Lecture-Notes/Basilisk101/3rd-workingAssignment)", + "content": "- **10:00-11:30**  |  **Lecture (2a)** - Interface tracking methods (VoF, level set, phase-field approaches) and numerical strategies - **11:45-13:00**  |  **Hackathon (2b)** - Hands-on tutorial with interface-tracking to a simple two-phase problem - [3rd Working Assignment](https://blogs.comphy-lab.org/Lecture-Notes/Basilisk101/3rd-workingAssignment)", "url": "/teaching/2025-Basilisk101-Madrid#Interface%2Btracking%2Bmethods", "type": "teaching_content", "priority": 2 }, { "title": "\"High-Fidelity Simulations Using Basilisk C\" - Interface tracking methods", - "content": "- **10:00-11:30**  |  **Lecture (2a)**\n - Interface tracking methods (VoF, level set, phase-field approaches) and numerical strategies\n- **11:45-13:00**  |  **Hackathon (2b)**\n - Hands-on tutorial with interface-tracking to a simple two-phase problem\n - [3rd Working Assignment](https://blogs.comphy-lab.org/Lecture-Notes/Basilisk101/3rd-workingAssignment)", + "content": "- **10:00-11:30**  |  **Lecture (2a)** - Interface tracking methods (VoF, level set, phase-field approaches) and numerical strategies - **11:45-13:00**  |  **Hackathon (2b)** - Hands-on tutorial with interface-tracking to a simple two-phase problem - [3rd Working Assignment](https://blogs.comphy-lab.org/Lecture-Notes/Basilisk101/3rd-workingAssignment)", "url": "/teaching/2025-Basilisk101-Madrid#Interface%2Btracking%2Bmethods", "type": "teaching_paragraph", "priority": 2 }, { "title": "\"High-Fidelity Simulations Using Basilisk C\" - Seminar", - "content": "- **13:30-14:00**  |  **Department seminar (2c)**\n - A note on the thrust of airfoils by [José Manuel Gordillo](https://scholar.google.com/citations?user=14wOsewAAAAJ&hl=en&inst=5726176096060060532&oi=ao)", + "content": "- **13:30-14:00**  |  **Department seminar (2c)** - A note on the thrust of airfoils by [José Manuel Gordillo](https://scholar.google.com/citations?user=14wOsewAAAAJ&hl=en&inst=5726176096060060532&oi=ao)", "url": "/teaching/2025-Basilisk101-Madrid#Seminar", "type": "teaching_content", "priority": 2 }, { "title": "\"High-Fidelity Simulations Using Basilisk C\" - Seminar", - "content": "- **13:30-14:00**  |  **Department seminar (2c)**\n - A note on the thrust of airfoils by [José Manuel Gordillo](https://scholar.google.com/citations?user=14wOsewAAAAJ&hl=en&inst=5726176096060060532&oi=ao)", + "content": "- **13:30-14:00**  |  **Department seminar (2c)** - A note on the thrust of airfoils by [José Manuel Gordillo](https://scholar.google.com/citations?user=14wOsewAAAAJ&hl=en&inst=5726176096060060532&oi=ao)", "url": "/teaching/2025-Basilisk101-Madrid#Seminar", "type": "teaching_paragraph", "priority": 2 }, { "title": "\"High-Fidelity Simulations Using Basilisk C\" - Non-Newtonian flows", - "content": "- **15:00-16:00**  |  **Lecture (3a)**\n - Non-Newtonian flows: viscoelasticity.\n- **16:15-18:00**  |  **Hackathon (3b)**\n - Coding exercises for viscoelastic fluids.\n - [4th Working Assignment](https://blogs.comphy-lab.org/Lecture-Notes/Basilisk101/4th-workingAssignment)", + "content": "- **15:00-16:00**  |  **Lecture (3a)** - Non-Newtonian flows: viscoelasticity. - **16:15-18:00**  |  **Hackathon (3b)** - Coding exercises for viscoelastic fluids. - [4th Working Assignment](https://blogs.comphy-lab.org/Lecture-Notes/Basilisk101/4th-workingAssignment)", "url": "/teaching/2025-Basilisk101-Madrid#Non-Newtonian%2Bflows", "type": "teaching_content", "priority": 2 }, { "title": "\"High-Fidelity Simulations Using Basilisk C\" - Non-Newtonian flows", - "content": "- **15:00-16:00**  |  **Lecture (3a)**\n - Non-Newtonian flows: viscoelasticity.\n- **16:15-18:00**  |  **Hackathon (3b)**\n - Coding exercises for viscoelastic fluids.\n - [4th Working Assignment](https://blogs.comphy-lab.org/Lecture-Notes/Basilisk101/4th-workingAssignment)", + "content": "- **15:00-16:00**  |  **Lecture (3a)** - Non-Newtonian flows: viscoelasticity. - **16:15-18:00**  |  **Hackathon (3b)** - Coding exercises for viscoelastic fluids. - [4th Working Assignment](https://blogs.comphy-lab.org/Lecture-Notes/Basilisk101/4th-workingAssignment)", "url": "/teaching/2025-Basilisk101-Madrid#Non-Newtonian%2Bflows", "type": "teaching_paragraph", "priority": 2 }, { "title": "\"High-Fidelity Simulations Using Basilisk C\" - Special topics", - "content": "- **10:00-11:30**  |  **Lecture (4a)**\n - Review and catching up on [4th Working Assignment](https://blogs.comphy-lab.org/Lecture-Notes/Basilisk101/4th-workingAssignment).\n - Special Topics: Three-phase flows, \n- **11:45-13:00**  |  **Hackathon (4b)**\n - Special Topics: Holey Sheets, Contact line dynamics. \n- **15:00-16:30**  |  **Lecture (4c)**\n - Open discussion, deeper dives into advanced features, final code reviews, and next steps.\n\n---", + "content": "- **10:00-11:30**  |  **Lecture (4a)** - Review and catching up on [4th Working Assignment](https://blogs.comphy-lab.org/Lecture-Notes/Basilisk101/4th-workingAssignment). - Special Topics: Three-phase flows, - **11:45-13:00**  |  **Hackathon (4b)** - Special Topics: Holey Sheets, Contact line dynamics. - **15:00-16:30**  |  **Lecture (4c)** - Open discussion, deeper dives into advanced features, final code reviews, and next steps. ---", "url": "/teaching/2025-Basilisk101-Madrid#Special%2Btopics", "type": "teaching_content", "priority": 2 }, { "title": "\"High-Fidelity Simulations Using Basilisk C\" - Special topics", - "content": "- **10:00-11:30**  |  **Lecture (4a)**\n - Review and catching up on [4th Working Assignment](https://blogs.comphy-lab.org/Lecture-Notes/Basilisk101/4th-workingAssignment).\n - Special Topics: Three-phase flows, \n- **11:45-13:00**  |  **Hackathon (4b)**\n - Special Topics: Holey Sheets, Contact line dynamics. \n- **15:00-16:30**  |  **Lecture (4c)**\n - Open discussion, deeper dives into advanced features, final code reviews, and next steps.", + "content": "- **10:00-11:30**  |  **Lecture (4a)** - Review and catching up on [4th Working Assignment](https://blogs.comphy-lab.org/Lecture-Notes/Basilisk101/4th-workingAssignment). - Special Topics: Three-phase flows, - **11:45-13:00**  |  **Hackathon (4b)** - Special Topics: Holey Sheets, Contact line dynamics. - **15:00-16:30**  |  **Lecture (4c)** - Open discussion, deeper dives into advanced features, final code reviews, and next steps. ---", "url": "/teaching/2025-Basilisk101-Madrid#Special%2Btopics", "type": "teaching_paragraph", "priority": 2 }, { "title": "\"High-Fidelity Simulations Using Basilisk C\" - Prerequisites", - "content": "- Basic knowledge of fluid mechanics\n- Experience with programming (any language, C preferred)\n- Understanding of partial differential equations\n- Laptop with ability to compile C code", + "content": "- Basic knowledge of fluid mechanics - Experience with programming (any language, C preferred) - Understanding of partial differential equations - Laptop with ability to compile C code", "url": "/teaching/2025-Basilisk101-Madrid#Prerequisites", "type": "teaching_content", "priority": 2 }, { "title": "\"High-Fidelity Simulations Using Basilisk C\" - Prerequisites", - "content": "- Basic knowledge of fluid mechanics\n- Experience with programming (any language, C preferred)\n- Understanding of partial differential equations\n- Laptop with ability to compile C code", + "content": "- Basic knowledge of fluid mechanics - Experience with programming (any language, C preferred) - Understanding of partial differential equations - Laptop with ability to compile C code", "url": "/teaching/2025-Basilisk101-Madrid#Prerequisites", "type": "teaching_paragraph", "priority": 2 }, { "title": "\"High-Fidelity Simulations Using Basilisk C\" - Registration", - "content": "For registration details, please contact \n
\n bubbles@ing.uc3m.es\n \n
\n
\n vatsalsy@comphy-lab.org\n \n
\n\n\n\n
\n \n Course GitHub Repository\n \n
", + "content": "For registration details, please contact bubbles@ing.uc3m.es vatsalsy@comphy-lab.org function copyEmail(button) { const textToCopy = button.getAttribute('data-text'); // Create a temporary textarea element to copy from const textarea = document.createElement('textarea'); textarea.value = textToCopy; textarea.setAttribute('readonly', ''); textarea.style.position = 'absolute'; textarea.style.left = '-9999px'; document.body.appendChild(textarea); // Select and copy the text textarea.select(); document.execCommand('copy'); // Remove the temporary element document.body.removeChild(textarea); // Show feedback const originalIcon = button.innerHTML; button.innerHTML = ' '; button.classList.add('copied'); // Restore original state after a delay setTimeout(() => { button.innerHTML = originalIcon; button.classList.remove('copied'); }, 2000); } Course GitHub Repository", "url": "/teaching/2025-Basilisk101-Madrid#Registration", "type": "teaching_content", "priority": 2 }, { "title": "\"High-Fidelity Simulations Using Basilisk C\" - Registration", - "content": "For registration details, please contact \n
\n bubbles@ing.uc3m.es\n \n
\n
\n vatsalsy@comphy-lab.org\n \n
", + "content": "For registration details, please contact bubbles@ing.uc3m.es vatsalsy@comphy-lab.org function copyEmail(button) { const textToCopy = button.getAttribute('data-text'); // Create a temporary textarea element to copy from const textarea = document.createElement('textarea'); textarea.value = textToCopy; textarea.setAttribute('readonly', ''); textarea.style.position = 'absolute'; textarea.style.left = '-9999px'; document.body.appendChild(textarea); // Select and copy the text textarea.select(); document.execCommand('copy'); // Remove the temporary element document.body.removeChild(textarea); // Show feedback const originalIcon = button.innerHTML; button.innerHTML = ' '; button.classList.add('copied'); // Restore original state after a delay setTimeout(() => { button.innerHTML = originalIcon; button.classList.remove('copied'); }, 2000); } Course GitHub Repository", "url": "/teaching/2025-Basilisk101-Madrid#Registration", "type": "teaching_paragraph", "priority": 2 }, { "title": "Teaching - Teaching", - "content": "Welcome to the CoMPhy Lab's educational resources. Apart from the university courses, we aim to develop and offer a range of workshops and tutorials on modern computational methods for multiphase flows and high-fidelity simulations.\n\n
\n
\n \"Basilisk\n
\n

High-Fidelity Simulations Using Basilisk C

\n
\n Universidad Carlos III de Madrid\n
\n
\n March 10-13, 2025\n
\n

\n A comprehensive course on using Basilisk C for simulating multiphase flows, interface tracking, and solving conservation equations. Learn to tackle complex fluid dynamics problems with high-fidelity numerical methods.\n

\n View Course\n
\n
\n
", + "content": "Welcome to the CoMPhy Lab's educational resources. Apart from the university courses, we aim to develop and offer a range of workshops and tutorials on modern computational methods for multiphase flows and high-fidelity simulations. High-Fidelity Simulations Using Basilisk C Universidad Carlos III de Madrid March 10-13, 2025 A comprehensive course on using Basilisk C for simulating multiphase flows, interface tracking, and solving conservation equations. Learn to tackle complex fluid dynamics problems with high-fidelity numerical methods. View Course", "url": "/teaching/#Teaching", "type": "teaching_content", "priority": 2 }, { "title": "Teaching - Teaching", - "content": "Welcome to the CoMPhy Lab's educational resources. Apart from the university courses, we aim to develop and offer a range of workshops and tutorials on modern computational methods for multiphase flows and high-fidelity simulations.", + "content": "Welcome to the CoMPhy Lab's educational resources. Apart from the university courses, we aim to develop and offer a range of workshops and tutorials on modern computational methods for multiphase flows and high-fidelity simulations. High-Fidelity Simulations Using Basilisk C Universidad Carlos III de Madrid March 10-13, 2025 A comprehensive course on using Basilisk C for simulating multiphase flows, interface tracking, and solving conservation equations. Learn to tackle complex fluid dynamics problems with high-fidelity numerical methods. View Course", "url": "/teaching/#Teaching", "type": "teaching_paragraph", "priority": 2 }, { "title": "Teaching - About Our Teaching Philosophy", - "content": "At CoMPhy Lab, we believe in hands-on learning and deep understanding of computational methods. Our courses combine theoretical foundations with practical implementation, allowing students to develop both conceptual understanding and technical skills.\n\nOur teaching approach emphasizes:\n\n- **Think before you compute**: Understanding the underlying physics before implementation\n- **Modular code structure**: Building maintainable and extensible computational tools\n- **Advanced numerical methods**: Mastering state-of-the-art techniques for complex problems\n- **Open science**: Sharing knowledge and tools with the scientific community. Checkout \n\nIf you're interested in hosting a course or workshop with CoMPhy Lab, please [contact us](/join) for collaboration opportunities.", + "content": "At CoMPhy Lab, we believe in hands-on learning and deep understanding of computational methods. Our courses combine theoretical foundations with practical implementation, allowing students to develop both conceptual understanding and technical skills. Our teaching approach emphasizes: - **Think before you compute**: Understanding the underlying physics before implementation - **Modular code structure**: Building maintainable and extensible computational tools - **Advanced numerical methods**: Mastering state-of-the-art techniques for complex problems - **Open science**: Sharing knowledge and tools with the scientific community. Checkout If you're interested in hosting a course or workshop with CoMPhy Lab, please [contact us](/join) for collaboration opportunities.", "url": "/teaching/#About%2BOur%2BTeaching%2BPhilosophy", "type": "teaching_content", "priority": 2 }, { "title": "Teaching - About Our Teaching Philosophy", - "content": "At CoMPhy Lab, we believe in hands-on learning and deep understanding of computational methods. Our courses combine theoretical foundations with practical implementation, allowing students to develop both conceptual understanding and technical skills.", + "content": "At CoMPhy Lab, we believe in hands-on learning and deep understanding of computational methods. Our courses combine theoretical foundations with practical implementation, allowing students to develop both conceptual understanding and technical skills. Our teaching approach emphasizes: - **Think before you compute**: Understanding the underlying physics before implementation - **Modular code structure**: Building maintainable and extensible computational tools - **Advanced numerical methods**: Mastering state-of-the-art techniques for complex problems - **Open science**: Sharing knowledge and tools with the scientific community. Checkout If you're interested in hosting a course or workshop with CoMPhy Lab, please [contact us](/join) for collaboration opportunities.", "url": "/teaching/#About%2BOur%2BTeaching%2BPhilosophy", "type": "teaching_paragraph", "priority": 2 }, { - "title": "Teaching - About Our Teaching Philosophy", - "content": "- **Think before you compute**: Understanding the underlying physics before implementation\n- **Modular code structure**: Building maintainable and extensible computational tools\n- **Advanced numerical methods**: Mastering state-of-the-art techniques for complex problems\n- **Open science**: Sharing knowledge and tools with the scientific community. Checkout ", - "url": "/teaching/#About%2BOur%2BTeaching%2BPhilosophy", - "type": "teaching_paragraph", - "priority": 2 + "title": "Build and Development Commands", + "content": "- **Install dependencies:** `bundle install && cd scripts && npm install && cd ..` - **Build site and search database:** `./scripts/build.sh` - **Run local server:** `bundle exec jekyll serve` (don't run this automatically, user will do manually) - **Fetch blog content:** `cd scripts && npm run fetch-github && cd ..` - **Generate search database:** `ruby scripts/generate_search_db.rb`", + "url": "/claude/#Build%2Band%2BDevelopment%2BCommands", + "type": "markdown_section", + "priority": 3 }, { - "title": "Teaching - About Our Teaching Philosophy", - "content": "If you're interested in hosting a course or workshop with CoMPhy Lab, please [contact us](/join) for collaboration opportunities.", - "url": "/teaching/#About%2BOur%2BTeaching%2BPhilosophy", - "type": "teaching_paragraph", - "priority": 2 + "title": "Build and Development Commands", + "content": "- **Install dependencies:** `bundle install && cd scripts && npm install && cd ..` - **Build site and search database:** `./scripts/build.sh` - **Run local server:** `bundle exec jekyll serve` (don't run this automatically, user will do manually) - **Fetch blog content:** `cd scripts && npm run fetch-github && cd ..` - **Generate search database:** `ruby scripts/generate_search_db.rb`", + "url": "/claude/#Build%2Band%2BDevelopment%2BCommands", + "type": "markdown_text", + "priority": 3 + }, + { + "title": "Repository Guidelines", + "content": "- Refer to README.md to understand the codebase structure and organization - After adding or deleting files, update README.md accordingly - Keep README.md up-to-date whenever changes affect what's documented there - Templates are in _layouts/*.html with corresponding CSS files: - default.html uses styles.css in /assets/css - research.html uses research.css - team.html uses team.css - All layouts use styles.css as base styling", + "url": "/claude/#Repository%2BGuidelines", + "type": "markdown_section", + "priority": 3 + }, + { + "title": "Repository Guidelines", + "content": "- Refer to README.md to understand the codebase structure and organization - After adding or deleting files, update README.md accordingly - Keep README.md up-to-date whenever changes affect what's documented there - Templates are in _layouts/*.html with corresponding CSS files: - default.html uses styles.css in /assets/css - research.html uses research.css - team.html uses team.css - All layouts use styles.css as base styling", + "url": "/claude/#Repository%2BGuidelines", + "type": "markdown_text", + "priority": 3 + }, + { + "title": "General", + "content": "- Use 2-space indentation across all files - Follow DRY principles: reuse components, variables, and styles - Add comments for complex logic, but keep code self-documenting - Support both light and dark themes for all new features and changes - Test all UI changes in both themes before committing - Use CSS variables for theme-specific colors (defined in styles.css)", + "url": "/claude/#General", + "type": "markdown_section", + "priority": 3 + }, + { + "title": "General", + "content": "- Use 2-space indentation across all files - Follow DRY principles: reuse components, variables, and styles - Add comments for complex logic, but keep code self-documenting - Support both light and dark themes for all new features and changes - Test all UI changes in both themes before committing - Use CSS variables for theme-specific colors (defined in styles.css)", + "url": "/claude/#General", + "type": "markdown_text", + "priority": 3 + }, + { + "title": "HTML/Markdown", + "content": "- Use semantic HTML elements - Follow BEM naming convention for CSS classes (e.g., `s-header__nav-list`) - Keep content files in markdown format where possible", + "url": "/claude/#HTMLMarkdown", + "type": "markdown_section", + "priority": 3 + }, + { + "title": "HTML/Markdown", + "content": "- Use semantic HTML elements - Follow BEM naming convention for CSS classes (e.g., `s-header__nav-list`) - Keep content files in markdown format where possible", + "url": "/claude/#HTMLMarkdown", + "type": "markdown_text", + "priority": 3 + }, + { + "title": "CSS", + "content": "- Use CSS variables for colors and typography (defined in `:root`) - Use responsive breakpoints at 1700px, 1300px, 900px, 768px, 500px - Use `rem` units for font sizes and spacing - Follow mobile-first approach for media queries - Implement dark theme styles using the [data-theme=\"dark\"] selector - Theme colors are defined in styles.css and page-specific CSS files", + "url": "/claude/#CSS", + "type": "markdown_section", + "priority": 3 + }, + { + "title": "CSS", + "content": "- Use CSS variables for colors and typography (defined in `:root`) - Use responsive breakpoints at 1700px, 1300px, 900px, 768px, 500px - Use `rem` units for font sizes and spacing - Follow mobile-first approach for media queries - Implement dark theme styles using the [data-theme=\"dark\"] selector - Theme colors are defined in styles.css and page-specific CSS files", + "url": "/claude/#CSS", + "type": "markdown_text", + "priority": 3 + }, + { + "title": "JavaScript", + "content": "- Use ES6+ features (arrow functions, const/let, template literals) - Always include 'use strict' mode - Use async/await for asynchronous operations - Implement error handling with try/catch blocks - Use camelCase for variable and function names - Prefer event delegation for multiple similar elements", + "url": "/claude/#JavaScript", + "type": "markdown_section", + "priority": 3 + }, + { + "title": "JavaScript", + "content": "- Use ES6+ features (arrow functions, const/let, template literals) - Always include 'use strict' mode - Use async/await for asynchronous operations - Implement error handling with try/catch blocks - Use camelCase for variable and function names - Prefer event delegation for multiple similar elements", + "url": "/claude/#JavaScript", + "type": "markdown_text", + "priority": 3 + }, + { + "title": "Images", + "content": "- Optimize images for web (compress to reduce file size) - Follow naming convention: `[name]-[descriptor].[extension]` - Include alt text for all images", + "url": "/claude/#Images", + "type": "markdown_section", + "priority": 3 + }, + { + "title": "Images", + "content": "- Optimize images for web (compress to reduce file size) - Follow naming convention: `[name]-[descriptor].[extension]` - Include alt text for all images", + "url": "/claude/#Images", + "type": "markdown_text", + "priority": 3 + }, + { + "title": "April", + "content": "- Vatsal Sanjay awarded the Ammodo Science Fellowship . His research will focus on understanding fluid dynamics in fungal networks—investigating how these vast underground systems transport water, nutrients, and genetic information across ecosystems. Read More Image credit: J. Heitman, B. J. Howlett, P. W. Crous, E. H. Stukenbrock, T. Y. James & N. A. R. Gow, The fungal kingdom, John Wiley & Sons (2020)", + "url": "/news/#April", + "type": "markdown_section", + "priority": 3 + }, + { + "title": "April", + "content": "- Vatsal Sanjay awarded the Ammodo Science Fellowship . His research will focus on understanding fluid dynamics in fungal networks—investigating how these vast underground systems transport water, nutrients, and genetic information across ecosystems. Read More Image credit: J. Heitman, B. J. Howlett, P. W. Crous, E. H. Stukenbrock, T. Y. James & N. A. R. Gow, The fungal kingdom, John Wiley & Sons (2020)", + "url": "/news/#April", + "type": "markdown_text", + "priority": 3 + }, + { + "title": "March", + "content": "- Prof. Detlef Lohse shares his scientific journey in The Living Histories Series . His inspiring discussion on curiosity, mentorship, and the \"puzzle solving\" joy of science offers valuable insights for researchers at all career stages. Watch on YouTube Sanjay, V. , & Lohse, D. Unifying theory of scaling in drop impact: Forces & maximum spreading diameter. Published in Physical Review Letters.](/research#15) View Paper --> - Join us for a hybrid online+offline course: [High-Fidelity Simulations Using Basilisk C](/teaching/2025-Basilisk101-Madrid) in Madrid, Spain (March 10-13). Learn some computational (colorful) fluid dynamics with hands-on coding sessions.", + "url": "/news/#March", + "type": "markdown_section", + "priority": 3 + }, + { + "title": "March", + "content": "- Prof. Detlef Lohse shares his scientific journey in The Living Histories Series . His inspiring discussion on curiosity, mentorship, and the \"puzzle solving\" joy of science offers valuable insights for researchers at all career stages. Watch on YouTube Sanjay, V. , & Lohse, D. Unifying theory of scaling in drop impact: Forces & maximum spreading diameter. Published in Physical Review Letters.](/research#15) View Paper --> - Join us for a hybrid online+offline course: [High-Fidelity Simulations Using Basilisk C](/teaching/2025-Basilisk101-Madrid) in Madrid, Spain (March 10-13). Learn some computational (colorful) fluid dynamics with hands-on coding sessions.", + "url": "/news/#March", + "type": "markdown_text", + "priority": 3 + }, + { + "title": "February", + "content": "- [ Sanjay, V. , Zhang, B., Lv, C., & Lohse, D. J. Fluid Mech., 1004, A6 (2025) selected as the cover article.](/research#14) Download Cover View Paper - Milan Sent graduated with a bachelor's degree from University of Twente. Thesis: Spinning Pizza", + "url": "/news/#February", + "type": "markdown_section", + "priority": 3 + }, + { + "title": "February", + "content": "- [ Sanjay, V. , Zhang, B., Lv, C., & Lohse, D. J. Fluid Mech., 1004, A6 (2025) selected as the cover article.](/research#14) Download Cover View Paper - Milan Sent graduated with a bachelor's degree from University of Twente. Thesis: Spinning Pizza", + "url": "/news/#February", + "type": "markdown_text", + "priority": 3 + }, + { + "title": "December", + "content": "[Balasubramanian, A. G., Sanjay, V. , Jalaal, M., Vinuesa, R., & Tammisola, O. J. Fluid Mech., 1001, A9 (2024). selected as the cover article.](/research#12) Download Cover View Paper", + "url": "/news/#December", + "type": "markdown_section", + "priority": 3 + }, + { + "title": "December", + "content": "[Balasubramanian, A. G., Sanjay, V. , Jalaal, M., Vinuesa, R., & Tammisola, O. J. Fluid Mech., 1001, A9 (2024). selected as the cover article.](/research#12) Download Cover View Paper", + "url": "/news/#December", + "type": "markdown_text", + "priority": 3 + }, + { + "title": "November", + "content": "Vatsal Sanjay recognized as an Outstanding Reviewer 2023 by the Journal of Fluid Mechanics for his contributions to the peer review process.", + "url": "/news/#November", + "type": "markdown_section", + "priority": 3 + }, + { + "title": "November", + "content": "Vatsal Sanjay recognized as an Outstanding Reviewer 2023 by the Journal of Fluid Mechanics for his contributions to the peer review process.", + "url": "/news/#November", + "type": "markdown_text", + "priority": 3 + }, + { + "title": "May", + "content": "Vatsal Sanjay awarded the KIVI Hoogendoorn Fluid Mechanics Award 2023 for his PhD thesis \"Viscous Free-Surface Flows\". The award ceremony took place at the Burgers Symposium on 29–30 May 2024 in Lunteren.", + "url": "/news/#May", + "type": "markdown_section", + "priority": 3 + }, + { + "title": "May", + "content": "Vatsal Sanjay awarded the KIVI Hoogendoorn Fluid Mechanics Award 2023 for his PhD thesis \"Viscous Free-Surface Flows\". The award ceremony took place at the Burgers Symposium on 29–30 May 2024 in Lunteren.", + "url": "/news/#May", + "type": "markdown_text", + "priority": 3 + }, + { + "title": "About Us", + "content": "We are based at the Physics of Fluids Department at the University of Twente, where we investigate [**non-Newtonian free-surface flows**](/research/?tag=Non-Newtonian) and [**soft matter singularities**](/research/?tag=Soft-matter-singularities). Our group employs a synergy of continuum simulations, experiments (through collaborations), and theoretical analysis to understand phenomena ranging involving drops, bubbles, jets, sheets, and more. We strive to connect fundamental findings with real-world applications, from industrial processes to everyday fluid dynamics.", + "url": "/aboutcomphy/#About%2BUs", + "type": "markdown_section", + "priority": 3 + }, + { + "title": "About Us", + "content": "We are based at the Physics of Fluids Department at the University of Twente, where we investigate [**non-Newtonian free-surface flows**](/research/?tag=Non-Newtonian) and [**soft matter singularities**](/research/?tag=Soft-matter-singularities). Our group employs a synergy of continuum simulations, experiments (through collaborations), and theoretical analysis to understand phenomena ranging involving drops, bubbles, jets, sheets, and more. We strive to connect fundamental findings with real-world applications, from industrial processes to everyday fluid dynamics.", + "url": "/aboutcomphy/#About%2BUs", + "type": "markdown_text", + "priority": 3 + }, + { + "title": "Soft Matter Singularities", + "content": "We examine topological transitions in fluid systems—such as [**droplet impact**](/research/?tag=Drops), [**bubble bursting**](/research/?tag=Bubbles), and [**sheet fragmentation**](/research/?tag=Sheets) — where local instabilities drive fast, often dramatic flow dynamics. Our goal is to expose the universal mechanisms governing these [**singular**]((/research/?tag=Soft-matter-singularities)) events in soft matter.", + "url": "/aboutcomphy/#Soft%2BMatter%2BSingularities", + "type": "markdown_section", + "priority": 3 + }, + { + "title": "Soft Matter Singularities", + "content": "We examine topological transitions in fluid systems—such as [**droplet impact**](/research/?tag=Drops), [**bubble bursting**](/research/?tag=Bubbles), and [**sheet fragmentation**](/research/?tag=Sheets) — where local instabilities drive fast, often dramatic flow dynamics. Our goal is to expose the universal mechanisms governing these [**singular**]((/research/?tag=Soft-matter-singularities)) events in soft matter.", + "url": "/aboutcomphy/#Soft%2BMatter%2BSingularities", + "type": "markdown_text", + "priority": 3 + }, + { + "title": "Non-Newtonian Flows as the `Drosophila' of Continuum Mechanics", + "content": "From [**elastoviscoplastic**]((/research/?tag=Non-Newtonian)) bubble bursting and elastic sheet break-up to champagne [**bubble**](/research/?tag=Bubbles) bursting and classical Taylor–Culick retractions, non-Newtonian fluids serve as model systems to explore the fundamentals of continuum mechanics. By integrating high-fidelity simulations, analytical frameworks, and collaborative experiments, we reveal how microstructural stresses affect fluid and solid dynamics. This research provides key insights for industrial and environmental applications.", + "url": "/aboutcomphy/#Non-Newtonian%2BFlows%2Bas%2Bthe%2BDrosophila%27%2Bof%2BContinuum%2BMechanics", + "type": "markdown_section", + "priority": 3 + }, + { + "title": "Non-Newtonian Flows as the `Drosophila' of Continuum Mechanics", + "content": "From [**elastoviscoplastic**]((/research/?tag=Non-Newtonian)) bubble bursting and elastic sheet break-up to champagne [**bubble**](/research/?tag=Bubbles) bursting and classical Taylor–Culick retractions, non-Newtonian fluids serve as model systems to explore the fundamentals of continuum mechanics. By integrating high-fidelity simulations, analytical frameworks, and collaborative experiments, we reveal how microstructural stresses affect fluid and solid dynamics. This research provides key insights for industrial and environmental applications.", + "url": "/aboutcomphy/#Non-Newtonian%2BFlows%2Bas%2Bthe%2BDrosophila%27%2Bof%2BContinuum%2BMechanics", + "type": "markdown_text", + "priority": 3 + }, + { + "title": "Viscous Free-Surface Flows", + "content": "We investigate various viscous free-surface flows including inertial contact lines, [**bubble**](/research/?tag=Bubbles) removal, and focusing of [**waves**](/research/?tag=Waves). These phenomena are critical to energy transitions and manufacturing. For instance, a key challenge is optimizing bubble detachment in electrolysis to boost efficiency. This research involves advanced numerical methods and industry partnerships, with the broader aim of advancing technologies from chemical reactors to printing processes.", + "url": "/aboutcomphy/#Viscous%2BFree-Surface%2BFlows", + "type": "markdown_section", + "priority": 3 + }, + { + "title": "Viscous Free-Surface Flows", + "content": "We investigate various viscous free-surface flows including inertial contact lines, [**bubble**](/research/?tag=Bubbles) removal, and focusing of [**waves**](/research/?tag=Waves). These phenomena are critical to energy transitions and manufacturing. For instance, a key challenge is optimizing bubble detachment in electrolysis to boost efficiency. This research involves advanced numerical methods and industry partnerships, with the broader aim of advancing technologies from chemical reactors to printing processes.", + "url": "/aboutcomphy/#Viscous%2BFree-Surface%2BFlows", + "type": "markdown_text", + "priority": 3 + }, + { + "title": "Commitment to Open Science", + "content": "Open exchange of ideas drives our progress. We share our codes from the earliest stages of development, embracing transparent research practices to foster collaboration and reproducibility. We welcome inquiries and partnerships from the broader scientific community. Watchout for [![GitHub](https://img.shields.io/badge/GitHub-100000?style=flat-square&logo=github&logoColor=white)](https://github.com/comphy-lab) and [ ](https://github.com/comphy-lab \"Visit our GitHub organization\") on this website to interact with our codes. Feel free to contact us for discussions about our work or anything else related to fluid physics. Nothing is more exhilarating than a healthy scientific discussion.", + "url": "/aboutcomphy/#Commitment%2Bto%2BOpen%2BScience", + "type": "markdown_section", + "priority": 3 + }, + { + "title": "Commitment to Open Science", + "content": "Open exchange of ideas drives our progress. We share our codes from the earliest stages of development, embracing transparent research practices to foster collaboration and reproducibility. We welcome inquiries and partnerships from the broader scientific community. Watchout for [![GitHub](https://img.shields.io/badge/GitHub-100000?style=flat-square&logo=github&logoColor=white)](https://github.com/comphy-lab) and [ ](https://github.com/comphy-lab \"Visit our GitHub organization\") on this website to interact with our codes. Feel free to contact us for discussions about our work or anything else related to fluid physics. Nothing is more exhilarating than a healthy scientific discussion.", + "url": "/aboutcomphy/#Commitment%2Bto%2BOpen%2BScience", + "type": "markdown_text", + "priority": 3 + }, + { + "title": "Location & Website", + "content": "[![Location](https://img.shields.io/badge/-Physics%20of%20Fluids-4285F4?style=flat&logo=googlemaps&logoColor=white)](https://maps.app.goo.gl/jSTCYnfcndF1uZPV8) [![Website](https://img.shields.io/badge/-comphy--lab.org-4285F4?style=flat&logo=googlechrome&logoColor=white)](http://www.comphy-lab.org) [![Email](https://img.shields.io/badge/-mailto:vatsalsy@comphy--lab.org-EA4335?style=flat&logo=gmail&logoColor=white)](mailto:vatsalsy@comphy-lab.org) vatsalsy@comphy-lab.org", + "url": "/aboutcomphy/#Location%2BWebsite", + "type": "markdown_section", + "priority": 3 + }, + { + "title": "Location & Website", + "content": "[![Location](https://img.shields.io/badge/-Physics%20of%20Fluids-4285F4?style=flat&logo=googlemaps&logoColor=white)](https://maps.app.goo.gl/jSTCYnfcndF1uZPV8) [![Website](https://img.shields.io/badge/-comphy--lab.org-4285F4?style=flat&logo=googlechrome&logoColor=white)](http://www.comphy-lab.org) [![Email](https://img.shields.io/badge/-mailto:vatsalsy@comphy--lab.org-EA4335?style=flat&logo=gmail&logoColor=white)](mailto:vatsalsy@comphy-lab.org) vatsalsy@comphy-lab.org", + "url": "/aboutcomphy/#Location%2BWebsite", + "type": "markdown_text", + "priority": 3 + }, + { + "title": "Academic Profiles", + "content": "[![Google Scholar](https://img.shields.io/badge/-Google%20Scholar-4285F4?style=flat&logo=googlescholar&logoColor=white)](https://scholar.google.com/citations?user=tHb_qZoAAAAJ&hl=en) [![ORCID](https://img.shields.io/badge/-ORCID-A6CE39?style=flat&logo=orcid&logoColor=white)](https://orcid.org/0000-0002-4293-6099) [![arXiv](https://img.shields.io/badge/-arXiv-B31B1B?style=flat&logo=arxiv&logoColor=white)](https://arxiv.org/search/?query=vatsal+sanjay&searchtype=all&source=header) [![ResearchGate](https://img.shields.io/badge/-ResearchGate-00CCBB?style=flat&logo=researchgate&logoColor=white)](https://www.researchgate.net/profile/Vatsal-Sanjay-2)", + "url": "/aboutcomphy/#Academic%2BProfiles", + "type": "markdown_section", + "priority": 3 + }, + { + "title": "Academic Profiles", + "content": "[![Google Scholar](https://img.shields.io/badge/-Google%20Scholar-4285F4?style=flat&logo=googlescholar&logoColor=white)](https://scholar.google.com/citations?user=tHb_qZoAAAAJ&hl=en) [![ORCID](https://img.shields.io/badge/-ORCID-A6CE39?style=flat&logo=orcid&logoColor=white)](https://orcid.org/0000-0002-4293-6099) [![arXiv](https://img.shields.io/badge/-arXiv-B31B1B?style=flat&logo=arxiv&logoColor=white)](https://arxiv.org/search/?query=vatsal+sanjay&searchtype=all&source=header) [![ResearchGate](https://img.shields.io/badge/-ResearchGate-00CCBB?style=flat&logo=researchgate&logoColor=white)](https://www.researchgate.net/profile/Vatsal-Sanjay-2)", + "url": "/aboutcomphy/#Academic%2BProfiles", + "type": "markdown_text", + "priority": 3 + }, + { + "title": "Social Media", + "content": "[![X](https://img.shields.io/badge/-@CoMPhyLab-000000?style=flat&logo=x&logoColor=white)](https://twitter.com/VatsalSanjay) [![Bluesky](https://img.shields.io/badge/-@comphy--lab.org-0285FF?style=flat&logo=bluesky&logoColor=white)](https://bsky.app/profile/comphy-lab.org) For supplementary videos and teaser of our upcoming work:", + "url": "/aboutcomphy/#Social%2BMedia", + "type": "markdown_section", + "priority": 3 + }, + { + "title": "Social Media", + "content": "[![X](https://img.shields.io/badge/-@CoMPhyLab-000000?style=flat&logo=x&logoColor=white)](https://twitter.com/VatsalSanjay) [![Bluesky](https://img.shields.io/badge/-@comphy--lab.org-0285FF?style=flat&logo=bluesky&logoColor=white)](https://bsky.app/profile/comphy-lab.org) For supplementary videos and teaser of our upcoming work:", + "url": "/aboutcomphy/#Social%2BMedia", + "type": "markdown_text", + "priority": 3 }, { "title": "0_README - Welcome to the CoMPhy Lab's documentation hub", diff --git a/scripts/build.sh b/scripts/build.sh index cff3e6a..81f4848 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -9,28 +9,10 @@ echo "Starting build process..." echo "Installing dependencies..." bundle install -# Install Node.js dependencies for blog content fetching -echo "Installing Node.js dependencies..." -cd scripts -npm install -cd .. - -# Fetch blog content from GitHub repository -echo "Fetching blog content from GitHub repository..." -cd scripts -npm run fetch-github -cd .. - # Build the Jekyll site echo "Building Jekyll site..." JEKYLL_ENV=production bundle exec jekyll build -# Generate search database -echo "Generating search database..." -cd scripts -bundle exec ruby generate_search_db.rb -cd .. - # Generate pre-filtered research pages echo "Generating pre-filtered research pages..." bundle exec ruby scripts/generate_filtered_research.rb diff --git a/scripts/fetch_github_blog_content.js b/scripts/fetch_github_blog_content.js deleted file mode 100644 index 6ef749d..0000000 --- a/scripts/fetch_github_blog_content.js +++ /dev/null @@ -1,175 +0,0 @@ -const fs = require('fs').promises; -const path = require('path'); -const { execSync } = require('child_process'); -const matter = require('gray-matter'); - -const OUTPUT_FILE = path.join(__dirname, 'blog_content.json'); -const REPO_URL = 'https://github.com/comphy-lab/CoMPhy-Lab-Blogs.git'; -const TEMP_DIR = path.join(__dirname, 'temp_blog_repo'); - -async function cloneRepository() { - console.log(`Cloning repository from ${REPO_URL}...`); - try { - // Remove temp directory if it exists - try { - await fs.rm(TEMP_DIR, { recursive: true, force: true }); - } catch (error) { - // Ignore if directory doesn't exist - } - - // Clone the repository - execSync(`git clone ${REPO_URL} ${TEMP_DIR}`, { stdio: 'inherit' }); - console.log('Repository cloned successfully'); - } catch (error) { - console.error('Error cloning repository:', error); - throw error; - } -} - -async function getMarkdownFiles(dir, fileList = []) { - const files = await fs.readdir(dir, { withFileTypes: true }); - - for (const file of files) { - const fullPath = path.join(dir, file.name); - - if (file.isDirectory()) { - // Skip .git, .github, and other hidden directories - if (!file.name.startsWith('.')) { - await getMarkdownFiles(fullPath, fileList); - } - } else if (file.name.endsWith('.md')) { - fileList.push(fullPath); - } - } - - return fileList; -} - -async function processBlogContent() { - const allEntries = []; - - try { - // Get all markdown files - const mdFiles = await getMarkdownFiles(TEMP_DIR); - console.log(`Found ${mdFiles.length} markdown files`); - - for (const filePath of mdFiles) { - const relativePath = path.relative(TEMP_DIR, filePath); - - // Skip files with "todo" in the name (case insensitive) - if (relativePath.toLowerCase().includes('todo')) { - console.log(`Skipping todo file: ${relativePath}`); - continue; - } - - try { - const fileContent = await fs.readFile(filePath, 'utf8'); - const { data, content } = matter(fileContent); - - // Skip files where publish is explicitly set to false - if (data.publish === false) { - console.log(`Skipping unpublished file: ${relativePath}`); - continue; - } - - // Get the URL based on the file path, converting to the format that would be used on the Obsidian Publish site - const urlPath = relativePath.replace(/\.md$/, '').replace(/\\/g, '/'); - const url = `https://blogs.comphy-lab.org/${urlPath}`; - - // Get the title from frontmatter or use filename - const title = data.title || path.basename(filePath, '.md'); - - // Clean up the content - const cleanContent = content - .replace(/^(created|status|modified|author|date published):.*$/gm, '') - .replace(/\n+/g, '\n') - .trim(); - - // Split content by headers - const sections = cleanContent.split(/(?=^#+\s+)/).map(s => s.trim()).filter(s => s); - - // If no headers found, treat the whole content as one section - const sectionsToProcess = sections.length > 0 ? sections : [cleanContent]; - - for (const section of sectionsToProcess) { - // Get section title - let sectionTitle; - let sectionContent; - - if (section.match(/^#+\s+/)) { - // If section starts with header, use it as title - const lines = section.split('\n'); - sectionTitle = lines[0].replace(/^#+\s+/, ''); - sectionContent = lines.slice(1).join('\n').trim(); - } else { - // Otherwise use main title - sectionTitle = title; - sectionContent = section; - } - - // Skip if no content left - if (!sectionContent) continue; - - // Split content into paragraphs - const paragraphs = sectionContent.split(/\n\n+/).map(p => p.trim()).filter(p => p); - - for (const para of paragraphs) { - // Skip code blocks, HTML and formatting-only content - if (para.startsWith('```') || para.startsWith('<') || para.match(/^[\s#*\-]+$/)) { - continue; - } - - // Skip very short paragraphs - if (para.length < 50) continue; - - // Create blog entry - allEntries.push({ - title: `${title} - ${sectionTitle}`, - content: para, - url: url, - type: 'blog_excerpt', - priority: 3 - }); - } - } - - } catch (error) { - console.error(`Error processing file ${filePath}:`, error.message); - } - } - - console.log(`Generated ${allEntries.length} searchable entries from blog content`); - return allEntries; - - } catch (error) { - console.error('Error processing blog content:', error); - return []; - } -} - -async function cleanup() { - console.log('Cleaning up temporary files...'); - try { - await fs.rm(TEMP_DIR, { recursive: true, force: true }); - console.log('Cleanup completed'); - } catch (error) { - console.error('Error during cleanup:', error); - } -} - -(async () => { - try { - console.log('Starting GitHub blog content fetch...'); - await cloneRepository(); - const entries = await processBlogContent(); - - await fs.writeFile(OUTPUT_FILE, JSON.stringify(entries, null, 2)); - console.log(`Written blog content to ${OUTPUT_FILE}`); - - await cleanup(); - } catch (error) { - console.error('Error:', error); - await cleanup(); - process.exit(1); - } -})(); \ No newline at end of file diff --git a/scripts/generate_search_db.rb b/scripts/generate_search_db.rb deleted file mode 100644 index 867de55..0000000 --- a/scripts/generate_search_db.rb +++ /dev/null @@ -1,621 +0,0 @@ -#!/usr/bin/env ruby -require 'json' -require 'nokogiri' -require 'fileutils' -require 'open-uri' -require 'net/http' -require 'uri' -require 'set' -require 'thread' # This provides Queue - -# Get the project root directory (one level up from scripts) -ROOT_DIR = File.expand_path('..', __dir__) - -# Initialize search database -search_db = [] - -# Helper function to generate proper anchor links -def generate_anchor(text) - # Remove date prefix if present (e.g., "2025-01-21 ") - text = text.sub(/^\d{4}-\d{2}-\d{2}\s+/, '') - - # Remove markdown link syntax if present [[text]] - text = text.gsub(/\[\[(.*?)\]\]/, '\1') - - # Remove any other markdown formatting - text = text.gsub(/[*_`]/, '') - - # Keep special characters that are part of the title - text = text.gsub(/[^\w\s\-':]/, '') - - # Replace spaces with + - text = text.gsub(/\s+/, '+') - - # Ensure special characters are properly encoded - URI.encode_www_form_component(text) -end - -# Process team members first (highest priority) -Dir.glob(File.join(ROOT_DIR, '_team', '*.md')).each do |file| - puts "Processing team member file #{file}..." - - content = File.read(file) - - # Split content by headers - sections = content.split(/^#+\s+/) - sections.shift # Remove content before first header - - sections.each do |section| - next if section.strip.empty? - - # Extract header and content - lines = section.lines - header = lines.first.strip - content = lines[1..].join.strip - - next if header.empty? || content.empty? - next unless header.match?(/^[^#]+/) # Skip if header starts with # - - # Create high-priority entry for team member - entry = { - 'title' => header, - 'content' => content, - 'url' => '/team/#' + header.downcase.gsub(/[^a-z0-9]+/, '-'), - 'type' => 'team_member', - 'priority' => 1 # Highest priority for team members - } - search_db << entry - end -end - -# Process markdown files first -Dir.glob(File.join(ROOT_DIR, '*.md')).each do |file| - next if file.start_with?(File.join(ROOT_DIR, '_team')) # Skip team members - next if File.basename(file).downcase == 'readme.md' # Skip README.md file (improved check) - - puts "Processing markdown file #{file}..." - - content = File.read(file) - is_readme = file.end_with?('README.md') - - # Skip processing completely if it's README.md - next if is_readme - - # Split content by headers - sections = content.split(/^#+\s+/) - sections.shift # Remove content before first header - - sections.each do |section| - next if section.strip.empty? - - # Extract header and content - lines = section.lines - header = lines.first.strip - content = lines[1..].join.strip - - next if header.empty? || content.empty? - next if content.length < 50 # Skip very short sections - - # Skip navigation-like sections - next if header.match?(/^(navigation|menu|contents|index)$/i) - - # Create entry for the section - entry = { - 'title' => header, - 'content' => content, - 'url' => is_readme ? '/README.md' : '/#about', - 'type' => is_readme ? 'readme_section' : 'markdown_section', - 'priority' => is_readme ? 4 : 3 # Lower priority for README sections - } - search_db << entry - - # Only create paragraph entries for non-README content - unless is_readme - # Also create entries for individual paragraphs - paragraphs = content.split(/\n\n+/) - paragraphs.each do |para| - para = para.strip - next if para.empty? - next if para.length < 100 # Only include substantial paragraphs - next if para.start_with?('```') # Skip code blocks - next if para.start_with?('<') # Skip HTML - - entry = { - 'title' => header, - 'content' => para, - 'url' => '/#about', - 'type' => 'markdown_text', - 'priority' => 3 - } - search_db << entry - end - end - end -end - -# Process teaching content from _teaching directory -Dir.glob(File.join(ROOT_DIR, '_teaching', '*.md')).each do |file| - puts "Processing teaching file #{file}..." - - content = File.read(file) - - # Extract YAML front matter to get permalink - front_matter = {} - if content.start_with?("---\n") - _, yaml_text, content = content.split("---\n", 3) - yaml_text.lines.each do |line| - if line.include?(":") - key, value = line.split(":", 2).map(&:strip) - front_matter[key] = value - end - end - end - - # Determine the URL for this teaching content - url = front_matter['permalink'] || '/teaching/' - - # Get the title from front matter or filename - title = front_matter['title'] || File.basename(file, '.md').gsub(/^\d{4}-/, '').tr('-', ' ') - - # Split content by headers - sections = content.split(/^#+\s+/) - sections.shift # Remove content before first header - - sections.each do |section| - next if section.strip.empty? - - # Extract header and content - lines = section.lines - header = lines.first.strip - content = lines[1..].join.strip - - next if header.empty? || content.empty? - next if content.length < 50 # Skip very short sections - - # Skip navigation-like sections - next if header.match?(/^(navigation|menu|contents|index)$/i) - - # Create entry for the section - entry = { - 'title' => "#{title} - #{header}", - 'content' => content, - 'url' => "#{url}##{generate_anchor(header)}", - 'type' => 'teaching_content', - 'priority' => 2 # Medium-high priority for teaching content - } - search_db << entry - - # Also create entries for individual paragraphs - paragraphs = content.split(/\n\n+/) - paragraphs.each do |para| - para = para.strip - next if para.empty? - next if para.length < 100 # Only include substantial paragraphs - next if para.start_with?('```') # Skip code blocks - next if para.start_with?('<') # Skip HTML - - entry = { - 'title' => "#{title} - #{header}", - 'content' => para, - 'url' => "#{url}##{generate_anchor(header)}", - 'type' => 'teaching_paragraph', - 'priority' => 2 - } - search_db << entry - end - end -end - -# Process each HTML file -Dir.glob(File.join(ROOT_DIR, '_site', '**', '*.html')) do |file| - next if file.include?('/assets/') # Skip asset files - - puts "Processing HTML file #{file}..." - - # Read and parse HTML - html = File.read(file) - doc = Nokogiri::HTML(html) - - # Get relative URL - url = file.sub(File.join(ROOT_DIR, '_site'), '') - - # Extract page title - title = doc.at_css('title')&.text || File.basename(file, '.html').capitalize - - # Special handling for teaching pages - if url.include?('/teaching/') - # Process course details - doc.css('.course-details__item').each do |detail| - heading = detail.at_css('h4')&.text.to_s.strip - content = detail.at_css('p')&.text.to_s.strip - - next if heading.empty? || content.empty? - - # Create entry for course detail - entry = { - 'title' => "#{title} - #{heading}", - 'content' => content, - 'url' => url, - 'type' => 'teaching_detail', - 'priority' => 2 # Medium-high priority - } - search_db << entry - end - - # Process course schedule/sections - doc.css('h3').each do |heading| - heading_text = heading.text.strip - next if heading_text.empty? - - # Get content until next h3 - content_nodes = [] - current = heading.next_element - while current && current.name != 'h3' - content_nodes << current.text.strip unless current.text.strip.empty? - current = current.next_element - end - content = content_nodes.join(' ').strip - next if content.empty? - - # Create entry for course section - entry = { - 'title' => "#{title} - #{heading_text}", - 'content' => content, - 'url' => "#{url}##{generate_anchor(heading_text)}", - 'type' => 'teaching_section', - 'priority' => 2 - } - search_db << entry - end - - # Process specific teaching sections like Prerequisites, Course Description, etc. - ['Prerequisites', 'Course Description', 'Registration', 'What will you learn'].each do |section_name| - section = doc.xpath("//h2[contains(text(), '#{section_name}')]").first - next unless section - - # Get content until next h2 - content_nodes = [] - current = section.next_element - while current && current.name != 'h2' - content_nodes << current.text.strip unless current.text.strip.empty? - current = current.next_element - end - content = content_nodes.join(' ').strip - next if content.empty? - - # Create entry for the specific section - entry = { - 'title' => "#{title} - #{section_name}", - 'content' => content, - 'url' => "#{url}##{generate_anchor(section_name)}", - 'type' => 'teaching_course_info', - 'priority' => 2 - } - search_db << entry - end - - # Process course card content on index page - doc.css('.course-card').each do |card| - card_title = card.at_css('.course-card__title')&.text.to_s.strip - card_desc = card.at_css('.course-card__desc')&.text.to_s.strip - card_meta = card.css('.course-card__meta').map(&:text).join(' - ').strip - - next if card_title.empty? && card_desc.empty? - - content = [card_title, card_meta, card_desc].reject(&:empty?).join(' - ') - - # Get link to course page - course_link = card.at_css('.course-card__link')&.[]('href').to_s - - # Create entry for course card - entry = { - 'title' => card_title.empty? ? "Teaching course" : card_title, - 'content' => content, - 'url' => course_link.empty? ? url : course_link, - 'type' => 'teaching_course', - 'priority' => 2 - } - search_db << entry - end - end - - # Special handling for team members - doc.css('h2').each do |heading| - name = heading.text.strip - next if name.empty? - - # Get content following the heading until the next h2 - content_nodes = [] - current = heading.next_element - while current && current.name != 'h2' - if current.text? - content_nodes << current.text.strip - elsif current.name == 'ul' || current.name == 'p' - content_nodes << current.text.strip - end - current = current.next_element - end - content = content_nodes.join(' ').strip - - # Create entry for team member - if content.include?('Research Interest') || content.include?('Collaboration on') || content.match?(/Ph\.D\.|Postdoc|Professor|Student/) - entry = { - 'title' => name, - 'content' => content, - 'url' => "#{url}##{generate_anchor(name)}", - 'type' => 'team_member', - 'priority' => 2 # Medium priority for team members - } - search_db << entry - end - end - - # Special handling for research papers (h3 with tags) - doc.css('h3').each do |heading| - next if heading.text.strip.empty? - - # Find the next tags element after this heading - tags_element = heading.xpath('following-sibling::tags[1]') - next unless tags_element.any? - - # Get tags - tags = tags_element.css('span').map(&:text).map(&:strip) - - # Get content between this heading and the next heading or tags - content_nodes = [] - current = heading.next_element - while current && !['h1', 'h2', 'h3', 'h4', 'h5', 'h6'].include?(current.name) && current.name != 'tags' - content_nodes << current.text.strip if current.text? - current = current.next_element - end - content = content_nodes.join(' ').strip - - # Create entry for paper - entry = { - 'title' => heading.text.strip, - 'content' => content, - 'url' => "#{url}##{generate_anchor(heading.text.strip)}", - 'type' => 'paper', - 'tags' => tags, - 'priority' => 3 # Lower priority for papers - } - search_db << entry - end - - # Process text content in chunks - doc.css('p').each do |para| - # Skip if this paragraph is part of a team member or paper section - next if para.ancestors('section').any? { |s| s['class']&.include?('team-member') } - next if para.xpath('./preceding-sibling::tags[1]').any? - next if para.xpath('./following-sibling::tags[1]').any? - - text = para.text.strip - next if text.empty? - - # Extract links from this paragraph - links = [] - para.css('a').each do |link| - href = link['href'] - next unless href && !href.start_with?('http') - links << href.sub(/^\//, '').sub(/\/$/, '') - end - - # Find the nearest heading - heading = para.xpath('./preceding::h1|./preceding::h2|./preceding::h3|./preceding::h4|./preceding::h5|./preceding::h6').last - heading_text = heading ? heading.text.strip : title - - # Create entry for text chunk - entry = { - 'title' => heading_text, - 'content' => text, - 'url' => "#{url}##{generate_anchor(heading_text)}", - 'type' => 'text', - 'links' => links, - 'priority' => 3 # Lower priority for regular content - } - search_db << entry - end - - # Process sections with headings - doc.css('h1, h2, h3').each do |heading| - # Skip team members and papers - next if heading.name == 'h2' && heading.text.strip.match?(/Ph\.D\.|Postdoc|Professor|Student/) - next if heading.name == 'h3' && heading.xpath('following-sibling::tags[1]').any? - - heading_text = heading.text.strip - next if heading_text.empty? - - # Get content until next heading of same or higher level - content_nodes = [] - current = heading.next_element - while current && !(current.name == heading.name || (current.name[1].to_i < heading.name[1].to_i && current.name.match?(/h[1-6]/))) - if current.text? - content_nodes << current.text.strip - elsif current.name == 'p' || current.name == 'ul' || current.name == 'ol' - content_nodes << current.text.strip - end - current = current.next_element - end - content = content_nodes.join(' ').strip - next if content.empty? - - # Extract links - links = [] - heading.parent.css('a').each do |link| - href = link['href'] - next unless href && !href.start_with?('http') - links << href.sub(/^\//, '').sub(/\/$/, '') - end - - # Create entry for section - entry = { - 'title' => heading_text, - 'content' => content, - 'url' => "#{url}##{generate_anchor(heading_text)}", - 'type' => 'section', - 'links' => links, - 'priority' => 3 # Lower priority for regular content - } - search_db << entry - end -end - -# Fetch and index external blog content -def fetch_blog_content - puts "Reading blog content from Node.js output..." - blog_content_file = File.join(File.dirname(__FILE__), 'blog_content.json') - - if File.exist?(blog_content_file) - begin - blog_entries = JSON.parse(File.read(blog_content_file)) - puts "Found #{blog_entries.length} blog entries" - - processed_entries = [] - - blog_entries.each do |entry| - # Skip empty entries - next if entry['content'].nil? || entry['content'].strip.empty? - - # Clean up the content first - content = entry['content'] - .gsub(/^(created|status|modified|author|date published):.*$/, '') # Remove metadata lines - .gsub(/\n+/, "\n") # Normalize newlines - .strip - - # First, try to split by headers - sections = content.split(/(?=^#+\s+)/).map(&:strip).reject(&:empty?) - - # If no headers found, treat the whole content as one section - sections = [content] if sections.empty? - - sections.each do |section| - # Get section title - title = if section.match?(/^#+\s+/) - # If section starts with header, use it as title - header = section.lines.first.strip - section = section.sub(/^#+\s+[^\n]+\n/, '').strip # Remove header from content - header.gsub(/^#+\s+/, '') - .sub(/\s*-\s*aliases:?\s*$/i, '') # Remove "- aliases" suffix - else - # Otherwise use first sentence or phrase as title - first_line = section.lines.first.strip - first_line.split(/[.!?]/).first - .sub(/\s*-\s*aliases:?\s*$/i, '') # Remove "- aliases" suffix - end - - # Clean up the title - title = title.gsub(/\s+/, ' ').strip # Normalize spaces - - # Generate a more descriptive title by combining blog title and section title - blog_title = entry['title'].sub(/\s+-\s+.*$/, '').strip - section_title = if title.downcase.start_with?(blog_title.downcase) - title # Use section title if it already includes blog title - else - "#{blog_title} - #{title}" # Combine blog title with section title - end - - # Skip if no content left after title - next if section.strip.empty? - - # Split content into paragraphs - paragraphs = section.split(/\n\n+/).map(&:strip).reject(&:empty?) - - paragraphs.each do |para| - # Skip code blocks and HTML - next if para.start_with?('```') || para.start_with?('<') - next if para.match?(/^[\s#*\-]+$/) # Skip lines that are just formatting - - # Split long paragraphs into smaller chunks - if para.length > 300 - # Split by sentences - sentences = para.split(/(?<=[.!?])\s+(?=[A-Z])/) - current_chunk = [] - current_length = 0 - - sentences.each do |sentence| - if current_length + sentence.length > 300 - # Store current chunk if not empty - if current_chunk.any? - chunk_text = current_chunk.join(' ').strip - if chunk_text.length >= 50 # Only store substantial chunks - processed_entries << { - 'title' => section_title, - 'content' => chunk_text, - 'url' => entry['url'], - 'type' => 'blog_excerpt', - 'priority' => 3 - } - end - current_chunk = [] - current_length = 0 - end - end - current_chunk << sentence - current_length += sentence.length - end - - # Store any remaining content - if current_chunk.any? - chunk_text = current_chunk.join(' ').strip - if chunk_text.length >= 50 - processed_entries << { - 'title' => section_title, - 'content' => chunk_text, - 'url' => entry['url'], - 'type' => 'blog_excerpt', - 'priority' => 3 - } - end - end - else - # For shorter paragraphs, store as is if substantial - if para.length >= 50 - processed_entries << { - 'title' => section_title, - 'content' => para, - 'url' => entry['url'], - 'type' => 'blog_excerpt', - 'priority' => 3 - } - end - end - end - end - end - - puts "Generated #{processed_entries.length} searchable entries from blog content" - processed_entries - rescue JSON::ParserError => e - puts "Error parsing blog content: #{e.message}" - [] - end - else - puts "No blog content file found. Run 'node scripts/fetch_blog_content.js' first." - [] - end -end - -begin - puts "Generating search database..." - - # Add blog entries to search database - search_db.concat(fetch_blog_content) - - # Write to JSON file in source assets/js directory first - source_file = File.join(File.dirname(__FILE__), '..', 'assets', 'js', 'search_db.json') - File.write(source_file, JSON.pretty_generate(search_db)) - puts "Written search database to #{source_file}" - - # Also write to _site directory if it exists (for local testing) - site_file = File.join(File.dirname(__FILE__), '..', '_site', 'assets', 'js', 'search_db.json') - if File.directory?(File.dirname(site_file)) - File.write(site_file, JSON.pretty_generate(search_db)) - puts "Written search database to #{site_file}" - end - - puts "Generated search database with #{search_db.length} entries" -rescue => e - puts "Error: #{e.message}" - puts e.backtrace - exit 1 -end diff --git a/scripts/package.json b/scripts/package.json deleted file mode 100644 index 9868d89..0000000 --- a/scripts/package.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "name": "comphy-lab-blog-crawler", - "version": "1.0.0", - "description": "Blog content crawler for CoMPhy Lab website", - "private": true, - "scripts": { - "fetch": "node fetch_blog_content.js", - "fetch-github": "node fetch_github_blog_content.js" - }, - "dependencies": { - "gray-matter": "^4.0.3" - }, - "optionalDependencies": { - "puppeteer": "^22.0.0" - }, - "engines": { - "node": ">=20.0.0" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/comphy-lab/comphy-lab.github.io.git" - }, - "author": "CoMPhy Lab", - "license": "MIT" -} \ No newline at end of file