Skip to main content
Glama
physics-adapter.js22.6 kB
/** * Enhanced Physics Adapter for Educational Content Generation * @module content-generation/physics-adapter * @description Specialized adapter for physics content with mathematical and scientific enhancements * @version 5.0.0-alpha */ import { BaseAdapter } from './base-adapter.js'; export class PhysicsAdapter extends BaseAdapter { constructor(config = {}) { super({ ...config, subject: 'física', enhancedFeatures: ['equations', 'calculations', 'diagrams', 'units'] }); // Initialize physics-specific capabilities this.initializePhysicsCapabilities(); } /** * Initialize physics-specific enhancement modules */ initializePhysicsCapabilities() { // Physics equation patterns and templates this.equationPatterns = { mechanics: { velocity: 'v = Δx/Δt', acceleration: 'a = Δv/Δt', force: 'F = ma', energy: 'E = ½mv²', momentum: 'p = mv', work: 'W = F·d', power: 'P = W/t' }, thermodynamics: { ideal_gas: 'PV = nRT', heat: 'Q = mcΔT', efficiency: 'η = W/Q', entropy: 'ΔS = Q/T' }, electromagnetics: { coulomb: 'F = kq₁q₂/r²', ohm: 'V = IR', power_electric: 'P = VI', magnetic_force: 'F = qvB', faraday: 'ε = -dΦ/dt' }, waves: { wave_equation: 'v = λf', period: 'T = 1/f', energy_wave: 'E = hf', doppler: "f' = f(v ± vₒ)/(v ± vₛ)" } }; // Unit conversion system this.unitConversions = { length: { 'm': 1, 'km': 1000, 'cm': 0.01, 'mm': 0.001 }, time: { 's': 1, 'min': 60, 'h': 3600, 'ms': 0.001 }, mass: { 'kg': 1, 'g': 0.001, 't': 1000 }, force: { 'N': 1, 'kN': 1000, 'dyn': 1e-5 } }; // Physics problem types this.problemTypes = { kinematics: ['motion', 'velocity', 'acceleration', 'trajectory'], dynamics: ['force', 'friction', 'momentum', 'collision'], energy: ['kinetic', 'potential', 'conservation', 'work'], thermodynamics: ['heat', 'temperature', 'entropy', 'efficiency'], waves: ['frequency', 'wavelength', 'interference', 'resonance'], electricity: ['current', 'voltage', 'resistance', 'circuits'], magnetism: ['field', 'flux', 'induction', 'magnetic_force'] }; // Physics diagram types this.diagramTypes = { force: 'Force diagrams and free body diagrams', motion: 'Trajectory plots and motion graphs', energy: 'Energy flow and transformation diagrams', wave: 'Wave patterns and interference diagrams', circuit: 'Electrical circuit schematics', field: 'Electric and magnetic field representations' }; } /** * Enhanced content generation with physics-specific features * @param {Object} topicAnalysis - Result from analyzeTopic * @param {Object} requirements - Content generation requirements * @returns {Promise<Object>} Enhanced physics content */ async generateContent(topicAnalysis, requirements = {}) { console.log('[PHYSICS-ADAPTER] Generating enhanced physics content for:', topicAnalysis.subject); try { // Generate base content first const baseContent = await super.generateContent(topicAnalysis, requirements); // Enhance with physics-specific content const enhancedContent = await this.enhanceWithPhysicsContent(baseContent, topicAnalysis); console.log('[PHYSICS-ADAPTER] Physics enhancement complete'); return enhancedContent; } catch (error) { console.error('[PHYSICS-ADAPTER] Enhanced content generation failed:', error); throw new Error(`Physics content generation failed: ${error.message}`); } } /** * Enhance base content with physics-specific features * @param {Object} baseContent - Base content from BaseAdapter * @param {Object} topicAnalysis - Topic analysis result * @returns {Promise<Object>} Enhanced content */ async enhanceWithPhysicsContent(baseContent, topicAnalysis) { const enhanced = { ...baseContent }; // Add physics metadata enhanced.metadata.subject = 'física'; enhanced.metadata.enhancedFeatures = this.config.enhancedFeatures; enhanced.metadata.physicsType = this.identifyPhysicsType(topicAnalysis); // Enhance explanation with equations and calculations if (enhanced.components.explanation) { enhanced.components.explanation = await this.enhanceExplanationWithPhysics( enhanced.components.explanation, topicAnalysis ); } // Enhance examples with physics problems if (enhanced.components.examples) { enhanced.components.examples = await this.enhanceExamplesWithPhysics( enhanced.components.examples, topicAnalysis ); } // Enhance assessment with physics problems if (enhanced.components.assessment) { enhanced.components.assessment = await this.enhanceAssessmentWithPhysics( enhanced.components.assessment, topicAnalysis ); } // Add physics-specific components enhanced.components.equations = await this.generateEquationsComponent(topicAnalysis); enhanced.components.diagrams = await this.generateDiagramsComponent(topicAnalysis); enhanced.components.calculations = await this.generateCalculationsComponent(topicAnalysis); return enhanced; } /** * Identify physics type from topic analysis * @param {Object} topicAnalysis - Topic analysis result * @returns {string} Physics type */ identifyPhysicsType(topicAnalysis) { const { keywords, concepts } = topicAnalysis; const allTerms = [...keywords, ...concepts].join(' ').toLowerCase(); // Check against physics problem types for (const [type, terms] of Object.entries(this.problemTypes)) { for (const term of terms) { if (allTerms.includes(term)) { return type; } } } // Default physics type based on common terms if (allTerms.includes('força') || allTerms.includes('movimento')) return 'dynamics'; if (allTerms.includes('energia') || allTerms.includes('trabalho')) return 'energy'; if (allTerms.includes('onda') || allTerms.includes('frequência')) return 'waves'; if (allTerms.includes('calor') || allTerms.includes('temperatura')) return 'thermodynamics'; if (allTerms.includes('elétrico') || allTerms.includes('corrente')) return 'electricity'; return 'kinematics'; // Default to kinematics } /** * Enhance explanation with physics content * @param {Object} explanation - Base explanation component * @param {Object} topicAnalysis - Topic analysis result * @returns {Promise<Object>} Enhanced explanation */ async enhanceExplanationWithPhysics(explanation, topicAnalysis) { const enhanced = { ...explanation }; // Add physics principles const physicsType = this.identifyPhysicsType(topicAnalysis); const principles = this.getPhysicsPrinciples(physicsType); // Enhance content with physics-specific information enhanced.content += '\n\n**Princípios Físicos Fundamentais:**\n'; enhanced.content += principles.join('\n• '); // Add mathematical formulation if applicable const equations = this.getRelevantEquations(physicsType); if (equations.length > 0) { enhanced.content += '\n\n**Formulação Matemática:**\n'; enhanced.content += equations.map(eq => `• ${eq}`).join('\n'); } // Add units and measurements const units = this.getRelevantUnits(physicsType); if (units.length > 0) { enhanced.content += '\n\n**Unidades de Medida:**\n'; enhanced.content += units.map(unit => `• ${unit}`).join('\n'); } return enhanced; } /** * Enhance examples with physics problems * @param {Object} examples - Base examples component * @param {Object} topicAnalysis - Topic analysis result * @returns {Promise<Object>} Enhanced examples */ async enhanceExamplesWithPhysics(examples, topicAnalysis) { const enhanced = { ...examples }; // Generate physics-specific examples const physicsType = this.identifyPhysicsType(topicAnalysis); const physicsExamples = this.generatePhysicsExamples(physicsType); enhanced.examples = [...enhanced.examples, ...physicsExamples]; enhanced.content += '\n\n**Exemplos de Problemas de Física:**\n'; enhanced.content += physicsExamples.map((ex, i) => `${i + 1}. ${ex}`).join('\n\n'); return enhanced; } /** * Enhance assessment with physics problems * @param {Object} assessment - Base assessment component * @param {Object} topicAnalysis - Topic analysis result * @returns {Promise<Object>} Enhanced assessment */ async enhanceAssessmentWithPhysics(assessment, topicAnalysis) { const enhanced = { ...assessment }; // Add physics-specific questions const physicsType = this.identifyPhysicsType(topicAnalysis); const physicsQuestions = this.generatePhysicsQuestions(physicsType, topicAnalysis); enhanced.questions = [...enhanced.questions, ...physicsQuestions]; return enhanced; } /** * Generate equations component * @param {Object} topicAnalysis - Topic analysis result * @returns {Promise<Object>} Equations component */ async generateEquationsComponent(topicAnalysis) { const physicsType = this.identifyPhysicsType(topicAnalysis); const equations = this.getRelevantEquations(physicsType); return { type: 'equations', title: 'Equações Fundamentais', content: 'As equações a seguir são fundamentais para compreender e resolver problemas relacionados ao tópico.', equations: equations, physicsType: physicsType, duration: '5-8 minutos' }; } /** * Generate diagrams component * @param {Object} topicAnalysis - Topic analysis result * @returns {Promise<Object>} Diagrams component */ async generateDiagramsComponent(topicAnalysis) { const physicsType = this.identifyPhysicsType(topicAnalysis); const diagramSuggestions = this.getDiagramSuggestions(physicsType); return { type: 'diagrams', title: 'Diagramas e Representações Visuais', content: 'Representações visuais são essenciais para compreender conceitos físicos.', suggestions: diagramSuggestions, physicsType: physicsType, duration: '8-12 minutos' }; } /** * Generate calculations component * @param {Object} topicAnalysis - Topic analysis result * @returns {Promise<Object>} Calculations component */ async generateCalculationsComponent(topicAnalysis) { const physicsType = this.identifyPhysicsType(topicAnalysis); const calculationSteps = this.getCalculationSteps(physicsType); return { type: 'calculations', title: 'Métodos de Cálculo', content: 'Passos sistemáticos para resolver problemas físicos.', steps: calculationSteps, physicsType: physicsType, duration: '10-15 minutos' }; } /** * Get physics principles for a given type * @param {string} physicsType - Type of physics * @returns {Array} Physics principles */ getPhysicsPrinciples(physicsType) { const principles = { kinematics: [ 'Movimento é a mudança de posição em relação ao tempo', 'Velocidade é a taxa de variação da posição', 'Aceleração é a taxa de variação da velocidade', 'Equações cinemáticas descrevem movimento uniformemente acelerado' ], dynamics: [ 'Primeira Lei de Newton: Lei da Inércia', 'Segunda Lei de Newton: F = ma', 'Terceira Lei de Newton: Ação e Reação', 'Conservação do momento linear' ], energy: [ 'Energia não pode ser criada nem destruída', 'Energia cinética: energia do movimento', 'Energia potencial: energia armazenada', 'Trabalho é transferência de energia' ], thermodynamics: [ 'Primeira Lei: Conservação de energia', 'Segunda Lei: Entropia sempre aumenta', 'Terceira Lei: Entropia zero no zero absoluto', 'Lei Zero: Equilíbrio térmico' ], waves: [ 'Ondas transportam energia sem transportar matéria', 'Frequência e período são inversamente proporcionais', 'Velocidade da onda depende do meio', 'Princípio da superposição' ], electricity: [ 'Lei de Coulomb: força entre cargas', 'Lei de Ohm: relação V-I-R', 'Conservação da carga elétrica', 'Leis de Kirchhoff para circuitos' ] }; return principles[physicsType] || principles.kinematics; } /** * Get relevant equations for physics type * @param {string} physicsType - Type of physics * @returns {Array} Relevant equations */ getRelevantEquations(physicsType) { const typeMapping = { kinematics: 'mechanics', dynamics: 'mechanics', energy: 'mechanics', thermodynamics: 'thermodynamics', waves: 'waves', electricity: 'electromagnetics' }; const category = typeMapping[physicsType] || 'mechanics'; const equations = this.equationPatterns[category] || {}; return Object.entries(equations).map(([name, equation]) => `${name.replace('_', ' ')}: ${equation}` ); } /** * Get relevant units for physics type * @param {string} physicsType - Type of physics * @returns {Array} Relevant units */ getRelevantUnits(physicsType) { const units = { kinematics: ['metro (m)', 'segundo (s)', 'metro por segundo (m/s)', 'metro por segundo² (m/s²)'], dynamics: ['newton (N)', 'quilograma (kg)', 'metro por segundo² (m/s²)', 'pascal (Pa)'], energy: ['joule (J)', 'watt (W)', 'quilograma (kg)', 'metro por segundo (m/s)'], thermodynamics: ['kelvin (K)', 'joule (J)', 'pascal (Pa)', 'metro³ (m³)'], waves: ['hertz (Hz)', 'metro (m)', 'segundo (s)', 'joule (J)'], electricity: ['ampere (A)', 'volt (V)', 'ohm (Ω)', 'coulomb (C)', 'watt (W)'] }; return units[physicsType] || units.kinematics; } /** * Generate physics-specific examples * @param {string} physicsType - Type of physics * @returns {Array} Physics examples */ generatePhysicsExamples(physicsType) { const examples = { kinematics: [ 'Um carro acelera de 0 a 60 km/h em 8 segundos. Calcule a aceleração.', 'Uma bola é lançada verticalmente para cima com velocidade inicial de 20 m/s. Determine a altura máxima.', 'Um projétil é lançado com ângulo de 45° e velocidade inicial de 30 m/s.' ], dynamics: [ 'Uma caixa de 10 kg é empurrada sobre uma superfície com coeficiente de atrito 0,3.', 'Dois carros colidem frontalmente: um de 1000 kg a 20 m/s e outro de 1500 kg a 15 m/s.', 'Um bloco de 5 kg está sobre um plano inclinado de 30°.' ], energy: [ 'Um pêndulo simples de 2 m de comprimento oscila com amplitude de 10°.', 'Uma mola com constante k=100 N/m é comprimida 0,2 m.', 'Um esquiador desce uma rampa de 50 m de altura.' ], thermodynamics: [ 'Um gás ideal passa por um processo isotérmico de 1 L para 2 L.', 'Uma máquina térmica opera entre reservatórios a 400 K e 300 K.', '100 g de água a 20°C são aquecidos até 80°C.' ], waves: [ 'Uma onda sonora de frequência 440 Hz se propaga no ar.', 'Interferência construtiva entre duas ondas de mesma amplitude.', 'Efeito Doppler: ambulância se aproximando a 30 m/s.' ], electricity: [ 'Circuito em série com resistores de 10 Ω, 20 Ω e 30 Ω.', 'Duas cargas de +2 μC e -3 μC separadas por 0,5 m.', 'Gerador de 12 V alimenta uma lâmpada de resistência 6 Ω.' ] }; return examples[physicsType] || examples.kinematics; } /** * Generate physics-specific questions * @param {string} physicsType - Type of physics * @param {Object} topicAnalysis - Topic analysis result * @returns {Array} Physics questions */ generatePhysicsQuestions(physicsType, topicAnalysis) { const questions = [ { type: 'multiple_choice', question: `Em problemas de ${physicsType}, qual é a grandeza física fundamental?`, options: [ 'Força', 'Energia', 'Momento', 'Todas as anteriores' ], correct: 3, explanation: 'Todas as grandezas são fundamentais dependendo do contexto do problema.' }, { type: 'calculation', question: `Resolva um problema típico de ${physicsType} aplicando as equações apropriadas.`, requiredSteps: ['Identificar dados', 'Escolher equação', 'Calcular', 'Verificar unidades'], physicsType: physicsType }, { type: 'conceptual', question: `Explique o princípio físico fundamental que governa ${topicAnalysis.subject}.`, keywords: ['princípio', 'fundamento', 'lei física', 'aplicação'], expectedLength: 'medium' } ]; return questions; } /** * Get diagram suggestions for physics type * @param {string} physicsType - Type of physics * @returns {Array} Diagram suggestions */ getDiagramSuggestions(physicsType) { const suggestions = { kinematics: [ 'Gráfico posição vs tempo', 'Gráfico velocidade vs tempo', 'Diagrama de trajetória', 'Representação vetorial do movimento' ], dynamics: [ 'Diagrama de corpo livre', 'Diagrama de forças', 'Representação de sistemas dinâmicos', 'Diagrama de momento' ], energy: [ 'Diagrama de conservação de energia', 'Representação de transformações energéticas', 'Gráfico energia vs posição', 'Diagrama de fluxo de energia' ], thermodynamics: [ 'Diagrama P-V (pressão-volume)', 'Ciclo termodinâmico', 'Diagrama de estados', 'Representação de processos térmicos' ], waves: [ 'Gráfico onda vs tempo', 'Padrão de interferência', 'Diagrama de ondas estacionárias', 'Representação do espectro' ], electricity: [ 'Esquema de circuito elétrico', 'Diagrama de campo elétrico', 'Representação de linhas equipotenciais', 'Diagrama de distribuição de cargas' ] }; return suggestions[physicsType] || suggestions.kinematics; } /** * Get calculation steps for physics type * @param {string} physicsType - Type of physics * @returns {Array} Calculation steps */ getCalculationSteps(physicsType) { const steps = { kinematics: [ '1. Identificar as grandezas conhecidas e desconhecidas', '2. Escolher o sistema de referência apropriado', '3. Selecionar a equação cinemática adequada', '4. Substituir os valores conhecidos', '5. Resolver a equação matematicamente', '6. Verificar unidades e razoabilidade do resultado' ], dynamics: [ '1. Desenhar o diagrama de corpo livre', '2. Identificar todas as forças atuantes', '3. Aplicar as Leis de Newton', '4. Definir sistema de coordenadas', '5. Resolver o sistema de equações', '6. Verificar o resultado fisicamente' ], energy: [ '1. Identificar os tipos de energia envolvidos', '2. Definir o sistema e suas fronteiras', '3. Aplicar o princípio de conservação', '4. Calcular energias inicial e final', '5. Considerar perdas ou ganhos de energia', '6. Verificar conservação total' ] }; return steps[physicsType] || steps.kinematics; } /** * Enhanced topic analysis for physics content * @param {string} topicDescription - Natural description of the physics topic * @returns {Promise<Object>} Enhanced physics topic analysis */ async analyzeTopic(topicDescription) { // Get base analysis const baseAnalysis = await super.analyzeTopic(topicDescription); // Add physics-specific analysis const physicsType = this.identifyPhysicsType(baseAnalysis); const mathematicalLevel = this.assessMathematicalLevel(topicDescription); const experimentalAspects = this.identifyExperimentalAspects(topicDescription); return { ...baseAnalysis, physicsType: physicsType, mathematicalLevel: mathematicalLevel, experimentalAspects: experimentalAspects, applicableEquations: this.getRelevantEquations(physicsType), suggestedDiagrams: this.getDiagramSuggestions(physicsType), unitSystem: this.getRelevantUnits(physicsType) }; } /** * Assess mathematical level required * @param {string} topicDescription - Topic description * @returns {string} Mathematical level */ assessMathematicalLevel(topicDescription) { const text = topicDescription.toLowerCase(); if (text.includes('integral') || text.includes('derivada') || text.includes('cálculo')) { return 'advanced'; } if (text.includes('equação') || text.includes('função') || text.includes('trigonometria')) { return 'intermediate'; } return 'basic'; } /** * Identify experimental aspects * @param {string} topicDescription - Topic description * @returns {Array} Experimental aspects */ identifyExperimentalAspects(topicDescription) { const text = topicDescription.toLowerCase(); const aspects = []; if (text.includes('experimento') || text.includes('laboratório')) { aspects.push('laboratory'); } if (text.includes('medida') || text.includes('medição')) { aspects.push('measurement'); } if (text.includes('erro') || text.includes('incerteza')) { aspects.push('uncertainty'); } if (text.includes('gráfico') || text.includes('dados')) { aspects.push('data_analysis'); } return aspects; } } // Factory function for creating PhysicsAdapter instances export function createPhysicsAdapter(config = {}) { return new PhysicsAdapter(config); }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/rkm097git/euconquisto-composer-mcp-poc'

If you have feedback or need assistance with the MCP directory API, please join our Discord server